n8n 워크플로가 실패했을 때 알아채는 장치 만들기 — 직접 만들어본 기록

지난 글에서 제일 찾기 어려웠던 실패는 실행 기록에 「완료됨」이 찍혔는데 메일이 없는 종류였습니다. 이번에는 그 문제를 n8n 쪽에서 다뤘습니다. 워크플로가 실패하면 메일이 오게 만들었습니다.

장치 자체는 노드 두 개입니다. 그런데 처음 두 번은 아무것도 안 왔습니다. 한 번은 알림 워크플로를 고를 수조차 없었고, 한 번은 골랐는데도 실패가 알림으로 이어지지 않았습니다. 그리고 알림이 오기 시작한 뒤에는 반대 문제가 생겼습니다 — 실패인데 초록 체크가 뜨는 경우가 세 종류 나왔습니다.

이 글은 그 순서 그대로입니다.

무엇을 만들었나

n8n 에는 Error Trigger 라는 노드가 있습니다. 다른 워크플로가 실패하면 이 노드가 대신 켜집니다. 그래서 알림 장치는 워크플로가 하나 더 필요합니다.

이름 하는 일
A 실패 알림 Error Trigger → Send Email
B 일부러 실패 1분마다 없는 주소를 호출
C 일부러 실패 1분마다 잘못된 코드를 실행

B 와 C 는 실험용입니다. 각각의 설정에서 「Error Workflow」 를 A 로 지정하면, B 나 C 가 넘어질 때 A 가 돕니다.

n8n 은 지난 설치 글과 같은 PC 의 같은 것입니다. 이번에 켤 때 167초 걸렸습니다. 세 번째 실행인데도 2분 이상입니다.

n8n 알림 워크플로 캔버스 — Error Trigger → 10분에 한 번만 → Send Email

막힌 지점 1 — 알림 워크플로가 회색으로 나옵니다

B 를 열고 오른쪽 위 「···」 → Settings 로 들어가면 두 번째 줄이 「Error Workflow (to notify when this one errors)」 입니다. 기본값은 「- No Workflow -」 입니다. 아무것도 안 하면 실패는 실행 목록에만 남습니다.

드롭다운을 열었더니 A 가 있긴 한데 회색이고 경고 아이콘이 붙어 있어서 고를 수가 없었습니다. 아이콘에 마우스를 올리니 이렇게 나옵니다.

Not published. Can be used for manual testing,
but must be published before running in production.
워크플로 설정의 Error Workflow 드롭다운 — 알림 워크플로가 회색이고 Not published 툴팁

알림 워크플로 A 를 먼저 Publish 해야 합니다. A 는 스케줄도 웹훅도 없어서 “켤” 이유가 없어 보이는데, 켜져 있어야 다른 워크플로가 고를 수 있습니다.

이 버전(2.8)은 예전의 「Active」 토글 대신 오른쪽 위에 「Publish」 버튼이 있습니다. 누르면 버전 이름을 묻는 창이 뜨고(기본값이 채워져 있습니다) 한 번 더 Publish 를 누르면 끝입니다. 그러고 나서 B 의 설정으로 돌아가니 A 가 검은 글씨로 바뀌어 고를 수 있었습니다.

막힌 지점 2 — 「Execute workflow」 로 실패시키면 아무것도 안 옵니다

A 를 지정하고 저장한 뒤, B 를 열어 아래의 「Execute workflow」 버튼을 눌렀습니다. HTTP 노드가 빨갛게 되고 오른쪽 아래에 이렇게 떴습니다.

Problem in node 'HTTP Request'
The resource you are requesting could not be found

실패했습니다. 그런데 메일이 없습니다. 실행 목록을 보니 B 는 manual · error 인데 A 는 실행조차 안 됐습니다. n8n 로그에도 아무 줄이 없습니다.

편집기에서 버튼으로 돌린 실행(manual)은 Error Workflow 를 부르지 않습니다. Error Trigger 는 Publish 된 워크플로가 스스로 돌다가 실패했을 때만 켜집니다. 지난 글에서 Apps Script 의 「실행」 버튼이 시험 용도가 아니었던 것과 같은 함정입니다.

B 도 Publish 했습니다. 1분마다 도는 스케줄이라 곧 실패합니다.

받았습니다 — 0.4초

시각
B Publish 누름 14:39:29
B 실패 (실행 4) 14:40:04.045
A 시작 (실행 5) 14:40:04.128
메일 서버 수신 14:40:04.439

실패에서 도착까지 0.4초입니다. 메일 본문은 이렇게 왔습니다.

워크플로: B. 일부러 실패 — 없는 주소 호출 (id xxxx)
실행 ID: 4
멈춘 노드: HTTP Request
모드: trigger
에러: The resource you are requesting could not be found
주소: http://localhost:5678/workflow/xxxx/executions/4

Send Email 노드의 제목·본문에 넣은 표현식은 이것입니다. Error Trigger 가 넘겨주는 값은 workflow 와 execution 두 묶음이었습니다.

제목  =[n8n 실패] {{ $json.workflow.name }}
본문  워크플로: {{ $json.workflow.name }} (id {{ $json.workflow.id }})
      실행 ID: {{ $json.execution.id }}
      멈춘 노드: {{ $json.execution.lastNodeExecuted }}
      에러: {{ $json.execution.error.message }}
      주소: {{ $json.execution.url }}

본문에 {{ JSON.stringify($json) }} 로 원문 전체를 붙였더니, 스택 트레이스 안에 이 PC 의 사용자 폴더 경로가 그대로 실려 왔습니다. C:\Users\사용자\AppData\... 식입니다. 회사 메일로 보낼 거면 위처럼 필요한 칸만 뽑는 편이 낫습니다.

n8n 실행 목록 — B·C 의 Error 와 A 의 Success 가 번갈아 찍힌 화면

돌려보니 알게 된 것

없는 주소인데 초록 체크가 뜹니다

사실 B 의 첫 버전은 실패하지 않았습니다. http://localhost:5678/this-page-does-not-exist 를 불렀는데 두 노드 다 초록 체크였습니다. 실행 기록도 success.

n8n 은 모르는 경로로 들어와도 화면용 HTML 을 200 으로 돌려줍니다. HTTP 노드는 200 이면 성공입니다. 받은 내용이 HTML 덩어리라는 건 아무도 안 봅니다. /rest/ 아래 주소로 바꾸고 나서야 404 가 나고 실패했습니다.

없는 주소를 호출했는데 두 노드가 초록 체크인 캔버스

Error Trigger 는 “노드가 넘어졌을 때”만 압니다. 상대 서버가 200 을 주면서 엉뚱한 것을 보내는 경우는 잡지 못합니다. 이건 n8n 이 아니라 상대 서버의 문제이고, 잡으려면 응답 내용을 검사하는 노드를 하나 더 붙여야 합니다.

잘못된 표현식도 실패가 아닙니다

C 의 첫 버전은 Edit Fields 노드에 {{ $json.customer.name.toUpperCase() }} 를 넣은 것이었습니다. customer 라는 칸은 없습니다. 자바스크립트라면 여기서 에러입니다.

성공했습니다. 결과는 name: null. 표현식은 없는 값을 만나면 조용히 비워 둡니다.

같은 경로를 Code 노드에 넣었더니 그제야 넘어졌습니다.

Problem in node 'Code'
Cannot read properties of undefined (reading 'name') [line 2]
같은 잘못된 경로 — Edit Fields 는 초록 체크, Code 노드는 빨간 X

같은 실수인데 한쪽은 초록, 한쪽은 빨강입니다. 표현식으로 만든 빈 값이 다음 노드로 흘러가 메일 제목이 null 로 나가도, Error Trigger 는 모릅니다.

「On Error → Continue」 를 켜면 실패가 성공이 됩니다

노드 설정에 「On Error」 항목이 있고 「Continue」 로 바꿀 수 있습니다. B 의 HTTP 노드를 그렇게 바꿔 봤습니다. 404 는 그대로인데 실행 기록이 success 로 바뀌고 알림이 끊겼습니다.

출력 아이템 안에는 error: { message: "404 - …", status: 404 } 가 들어 있습니다. 실패 정보는 남는데 실패로 세지 않는 겁니다. 이 옵션을 켠 노드는 알림 장치 밖에 있다고 보셔야 합니다.

저장했는데 반영이 안 됐습니다

위 「Continue」 실험에서 하나 더 걸렸습니다. 노드 설정을 바꿔 저장했는데 다음 실행이 여전히 실패로 찍혔습니다.

이 버전은 Publish 한 시점의 워크플로가 돕니다. 편집기에서 고쳐 저장한 것은 초안이고, 다시 Publish 를 눌러야 도는 것이 바뀝니다. 화면에서 보이는 차이는 오른쪽 위 버튼이 초록 「Published」 에서 노란 점이 붙은 「Publish」 로 바뀌는 것뿐입니다. 알림 워크플로 A 를 고칠 때도 마찬가지입니다 — 고치고 Publish 를 안 누르면 옛 버전이 알림을 보냅니다.

저장만 한 상태 — 오른쪽 위 Publish 버튼에 노란 점

1분에 두 통씩 옵니다

B 와 C 가 1분마다 실패하니 알림도 1분에 두 통입니다. 30분이면 60통이고, 그 시점부터 아무도 안 읽습니다.

지난 글에서 시트 D열에 「보낸 시각」을 적어 중복을 막았던 것과 같은 방법을 썼습니다. A 의 Error Trigger 와 Send Email 사이에 Code 노드를 하나 넣었습니다. n8n 은 워크플로마다 작은 저장 공간($getWorkflowStaticData)을 주는데, 거기에 워크플로별 마지막 발송 시각을 적어 둡니다.

// 같은 워크플로의 실패는 10분에 한 번만 알립니다
const store = $getWorkflowStaticData('global');
const key = 'lastAlert_' + $json.workflow.id;
const now = Date.now();
const WINDOW = 10 * 60 * 1000;
if (store[key] && now - store[key] < WINDOW) {
  return [];               // 최근에 보냈으면 여기서 끝 — 메일 안 감
}
store[key] = now;
return $input.all();

A 를 다시 Publish 하니 B·C 각 한 통이 오고, 그 뒤 A 는 매분 돌면서 메일은 0통이었습니다. 저장 공간을 열어 보니 두 워크플로의 시각이 적혀 있었습니다.

다만 한 번 뚫렸습니다. 아래 재기동 실험에서 A 두 개가 겹쳐 돌았을 때, 나중에 끝난 쪽이 낡은 값으로 덮어써서 같은 워크플로 알림이 32초 간격으로 두 번 왔습니다. 평소처럼 하나씩 돌 때는 문제가 없었고, 겹쳐 돌면 이 방식은 완전하지 않습니다.

메일 서버가 죽어 있으면 — 아무도 모릅니다

받는 서버를 껐습니다. 다음 실패에서 A 는 이렇게 끝났습니다.

The service refused the connection - perhaps it is offline
connect ECONNREFUSED 127.0.0.1:1025

A 는 실행 목록에 error 로 남습니다. 그런데 이 실패는 어디에도 알려지지 않습니다. 알림 워크플로 자신이 실패했을 때 그걸 또 알려 줄 워크플로는 없습니다. 지난 글에서 트리거 실패 알림 기본값이 「매일」이라 하루 뒤에야 알았던 것과 같은 구멍인데, 여기는 하루 뒤에도 안 옵니다.

n8n 을 껐다 켜면

n8n 을 끄고 다시 켰습니다. 재기동에 239초 걸렸습니다. 그 4분 동안 B·C 는 돌지 않았고, 놓친 실행을 나중에 몰아서 돌리지도 않습니다. 당연히 알림도 없습니다. n8n 자체가 꺼진 것은 n8n 안의 장치로는 못 잡습니다.

켜진 뒤에 하나 더 있었습니다. 설치 글에서 본 그 403 줄이 이번에는 스물두 번 반복됐고, 그동안 A 가 세 번 이렇게 실패했습니다.

Task request timed out after 60 seconds

제가 넣은 「10분에 한 번만」 Code 노드 때문입니다. Code 노드는 별도 실행기(task runner)에서 도는데, 재기동 후 그 실행기가 붙기까지 약 3분이 걸렸습니다. 실행기가 붙자 밀려 있던 알림 세 통이 같은 초에 한꺼번에 왔습니다. 위에서 말한 억제가 뚫린 것도 이때입니다.

이 구간은 실행 기록과 메일이 1:1 로 맞지 않았습니다. 타임아웃으로 error 가 된 A 실행의 알림이 나중에 도착했는데, 어떤 경로로 다시 보내진 것인지는 확인하지 못했습니다.

Code 노드가 없는 A(Error Trigger → Send Email 만)라면 이 3분은 문제가 안 됐을 겁니다. 중복 억제를 넣는 대가입니다.

시간대 기본값이 뉴욕입니다

워크플로 설정의 「Timezone」 기본값이 America/New York 이었습니다. 실행 기록의 시각도 2026-09-12T01:41:48-04:00 식으로 찍힙니다. 「매일 아침 9시」 스케줄을 걸기 전에 여기부터 바꾸셔야 합니다. 이 글의 시각은 전부 이 PC 시계(KST) 기준으로 다시 적은 것입니다.

이 방법이 안 맞는 경우

받는 쪽이 이 PC 의 시험용 메일 서버입니다. Send Email 노드의 SMTP 자격증명을 127.0.0.1:1025 로 넣었습니다. 실제 메일 계정(회사 메일이나 Gmail 의 앱 비밀번호)으로 바꾸면 노드는 같습니다만, 그 연결은 이 글에서 시험하지 않았습니다. 지난 글의 Apps Script 는 구글 계정만 있으면 메일이 나갔는데, n8n 은 보내는 메일 서버를 따로 연결해야 합니다.

메일 안의 「주소」 링크가 localhost 입니다. 이 PC 에서 n8n 을 돌리면 다른 기기에서는 그 링크가 안 열립니다. 서버에 올리거나 WEBHOOK_URL 을 잡아야 합니다.

n8n 이 꺼진 것, 메일 서버가 죽은 것은 못 잡습니다. 위에서 본 대로입니다. 이건 n8n 밖에서 n8n 이 살아 있는지 보는 장치가 따로 있어야 하고, 이 글의 범위 밖입니다.

요약

Error Workflow 가 회색 알림 워크플로를 먼저 Publish 하십시오
「Execute workflow」 로 실패시켰는데 안 옴 manual 실행은 Error Workflow 를 안 부릅니다. Publish 하고 스스로 돌게 하십시오
없는 주소인데 초록 체크 상대가 200 을 주면 성공입니다. 응답 내용은 따로 검사해야 합니다
{{ $json.a.b }} 가 틀렸는데 초록 표현식은 null 로 넘어갑니다. Code 노드여야 넘어집니다
「On Error → Continue」 실패가 success 로 바뀝니다. 알림 밖입니다
저장했는데 안 바뀜 다시 Publish 해야 도는 것이 바뀝니다
1분에 두 통 static data 에 마지막 발송 시각을 적어 10분에 한 번
ECONNREFUSED 알림 워크플로의 실패는 아무도 모릅니다
재기동 후 Task request timed out Code 노드는 실행기가 붙을 때까지 3분쯤 못 돕니다
Timezone America/New York 스케줄 걸기 전에 바꾸십시오

노드는 두 개였고, 시간이 간 곳은 Publish 와 “무엇을 실패로 치는가” 였습니다.


참고
– n8n 공식 문서 — Error Trigger 노드 (Error Trigger node)
– n8n 공식 문서 — 워크플로 설정의 Error Workflow (Workflow settings)

Leave a Comment