
A workflow that syncs orders or sends invoices fails at night, and you hear about it days later from a customer. n8n logged the failed run in its Executions list, where nobody looked. This guide sets up an alert for every failed run, keeps failed runs so you can retry them, adds retries for flaky nodes, and checks n8n from outside for the failures it can't report itself, such as a stopped container.
Quick answer: Build one workflow that starts with the Error Trigger node and ends in a Send Email, Discord or Telegram node, publish it, and select it under Error Workflow in the settings of each workflow you want watched. It runs when a production execution fails, never for test runs in the editor, so test it with a Stop And Error node on a schedule. Keep failed executions saved so you can retry them, use Retry On Fail for flaky nodes, and check /healthz/readiness and a heartbeat from another machine, because nothing alerts you when n8n itself is down.
Which Check Catches Which Failure
| What goes wrong | Does the error workflow run? | What catches it |
|---|---|---|
| A node fails in a published workflow | Yes | Error workflow alert |
| The trigger node fails | Yes, with trigger data instead of execution | Error workflow alert |
| A node set to a Continue option fails | No, if the nodes after it succeed | An alert node on its error output |
| You run the workflow from the editor | No | You see the error on the canvas |
| n8n, its database or the VPS is down | No | Outside check on /healthz/readiness |
| A workflow stops running, for example after it was unpublished | No | Heartbeat to a push monitor |
Step 1: Create the Error Workflow
- Create a new workflow with the Error Trigger as its first node, and name it something like
Error Handler. - Add the alert node from Step 2 after it, then select Publish.
- Open a workflow you want to watch, select the three dots menu at the top right, then Settings.
- Under Error Workflow (to notify when this one errors), choose
Error Handler, then select Save.
Repeat steps 3 and 4 for each workflow; one error workflow can serve them all (n8n's error handling page). Don't skip the publish: n8n 2.45.7 won't let you pick an unpublished workflow in that list (settings code) and skips one with "is not active and cannot be executed" (execution service), whatever the Error Trigger docs say. Alerts use the published version, so publish again after each change to Error Handler; a settings change goes live without a new publish (save and publish).
The Error Trigger receives data like n8n's example:
{
"execution": {
"id": "231",
"url": "https://n8n.example.com/execution/231",
"retryOf": "34",
"error": { "message": "Example Error Message", "stack": "Stacktrace" },
"lastNodeExecuted": "Node With Error",
"mode": "manual"
},
"workflow": { "id": "1", "name": "Example Workflow" }
}
id and url need a saved execution, and retryOf only appears on retries. When the watched workflow's trigger node fails, the data holds a trigger object with the error instead of execution.
Step 2: Send the Alert by Email, Discord or Telegram
Use this text in any of the three nodes, with the field in expression mode:
n8n workflow failed: {{ $json.workflow.name }}
Node: {{ $json.execution ? $json.execution.lastNodeExecuted : 'trigger' }}
Error: {{ ($json.execution || $json.trigger).error.message }}
Open: {{ $json.execution ? $json.execution.url : '' }}
The JavaScript checks on $json.execution (expressions docs) keep the message working when a trigger fails. Leave the stack trace out: a Discord message holds 2000 characters (Discord webhook docs) and a Telegram message 4096.
Email. Add a Send Email node with an SMTP credential from your mail provider: port 465 with SSL/TLS on, or port 587 with it off for STARTTLS (SMTP credential docs). Fill in From Email, To Email and a Subject such as n8n failed: {{ $json.workflow.name }}, set Email Format to Text (the default is HTML) and paste the template into Text.
Discord. Open Server Settings > Integrations in Discord, select Create Webhook, pick the channel and copy the webhook URL into an n8n Discord credential of the webhook type (Discord credential docs). In the Discord node, set Connection Type to Webhook, choose Send a Message and paste the template into Message.
Telegram. Send /newbot to @BotFather and use its token as the credential's Access Token (Telegram credential docs). Add the bot to a group, get the group's Chat ID, which starts with - in n8n (three ways to find it), then use Message > Send Message with that Chat ID and the template as Text. Unless you add the Parse Mode field, the node sends legacy Markdown, where Telegram reads _, *, ` and [ as formatting (Bot API), so an error such as invalid_grant can fail to send. Set Parse Mode to HTML, where only <, > and & are special.
Step 3: Test It With a Failure on Purpose
The Error Trigger "only runs when an automatic workflow errors" (n8n's lifecycle code skips manual runs), so Execute workflow in the editor never sends an alert. Instead:
- Create a workflow with a Schedule Trigger on the Minutes interval with
1in Minutes Between Triggers, followed by a Stop And Error node with the error messageTest alert. - Select
Error Handleras its error workflow and publish it. - Wait for the alert, then unpublish or delete the test workflow.
No alert within a few minutes? Open Error Handler and check its Executions tab, where a failing alert node shows up.
Step 4: Keep Failed Executions, Then Read and Retry Them
n8n saves failed production executions by default (EXECUTIONS_DATA_SAVE_ON_ERROR=all in the executions variables), and each workflow can override that under Save failed production executions. Keep it on, since you can only retry what n8n stores. To save disk space, stop saving successful runs instead, as n8n's execution data guide shows, in the n8n service of your compose file:
services:
n8n:
environment:
EXECUTIONS_DATA_SAVE_ON_ERROR: all
EXECUTIONS_DATA_SAVE_ON_SUCCESS: none
Then run sudo docker compose up -d, which recreates the container with the new settings (docker compose up).
To read failures, open the workflow's Executions tab, or Overview > Executions for all workflows, and filter on Status: Failed. On Registered Community, Business and Enterprise, Debug in editor copies a failed run's data into the canvas, so you can fix the workflow and re-run it on that data (debug executions).
To retry, select Retry execution on the failed run, then Retry with original workflow (enough if you only fixed a credential) or Retry with currently saved workflow (your fixed version). A retry resumes at the failed node and keeps the results of finished nodes, but the failed node processes all its input again: a node that sent some messages before failing sends them again (view all executions). Prefer update-or-insert operations for nodes that write data.
For errors outside workflows, read sudo docker compose logs --since 30m n8n (logs reference); N8N_LOG_LEVEL=debug adds detail (log variables).
Step 5: Retry Flaky Nodes Before They Alert You
An API that times out once a night shouldn't wake you up. In the node's Settings tab, turn on Retry On Fail. Max. Tries defaults to 3 and n8n uses 2 to 5; Wait Between Tries (ms) defaults to 1000 and goes up to 5000 (execution engine source). Only the last failed try fails the run and fires the alert.
The On Error setting decides what happens then (node settings):
- Stop Workflow halts and fails the execution, so the error workflow runs. Leaving the setting alone does the same.
- Continue moves on to the next node with the last valid data.
- Continue (using error output) sends the item to an extra
erroroutput.
With either Continue option, n8n treats the error as handled: the run carries on, and if the nodes after it succeed, n8n records a success and never calls the error workflow. When you use the error output, connect it to its own email, Discord or Telegram node.
Step 6: Health Checks and Metrics
n8n's monitoring page lists three endpoints. /healthz returns 200 when the instance is reachable, without checking the database; /healthz/readiness returns 200 only when the database is connected and migrated. The main instance always serves both; a queue mode worker needs QUEUE_HEALTH_CHECK_ACTIVE=true (port QUEUE_HEALTH_CHECK_PORT, default 5678). On the VPS, for example a Space-Node VPS for n8n and AI agents with full root access on KVM:
curl -i http://127.0.0.1:5678/healthz
curl -i http://127.0.0.1:5678/healthz/readiness
This assumes port 5678 is published as 127.0.0.1:5678:5678, which keeps it off the internet (our Docker and UFW guide explains why).
/metrics serves Prometheus metrics on all self-hosted editions, but is off by default. To count failures, turn on the event metrics too:
services:
n8n:
environment:
N8N_METRICS: "true"
N8N_METRICS_INCLUDE_MESSAGE_EVENT_BUS_METRICS: "true"
N8N_METRICS_INCLUDE_WORKFLOW_ID_LABEL: "true"
Compose wants true in quotes, or YAML turns it into a boolean (services reference). After sudo docker compose up -d, n8n keeps a counter per event, named after it: n8n.workflow.failed becomes n8n_workflow_failed_total, with a workflow_id label from the last line (metrics source). The counter appears after the first failure since n8n started:
curl -s http://127.0.0.1:5678/metrics | grep n8n_workflow_failed_total
Prometheus can scrape this and alert when it rises. But n8n warns not to expose /metrics publicly, and an Nginx proxy that forwards / to n8n forwards that path too. Block it in the n8n server block (access module, location):
location = /metrics {
deny all;
}
Then run sudo nginx -t && sudo nginx -s reload (command line).
Step 7: Check n8n From Another Machine
Everything above runs inside n8n, so a stopped container, a database that's down or a VPS that's off sends no alert. A monitor on another machine covers that; one on the same VPS goes down with it. Uptime Kuma (see our Uptime Kuma guide) is one option: it alerts through Telegram, Discord, email and 90+ other services, and its README starts it with:
sudo docker run -d --restart=always -p 3001:3001 -v uptime-kuma:/app/data --name uptime-kuma louislam/uptime-kuma:2
Add two monitors:
- HTTP(s) on
https://n8n.example.com/healthz/readiness. By default it checks every 60 seconds and accepts status codes 200 to 299 (monitor defaults), so a stopped n8n, a broken proxy or a lost database connection all show up. - Push, as a heartbeat. Kuma shows a push URL like
https://kuma.example.com/api/push/<token>?status=up&msg=OK&ping=. In n8n, publish a workflow with a Schedule Trigger every 5 minutes and an HTTP Request node that sends a GET to that URL. Set the monitor's Heartbeat Interval to 360 seconds: when no push arrives in time, Kuma marks it down with "No heartbeat in the time window" (monitor source).
That proves n8n still runs schedules. For your most important workflow, add a request to its own push URL as the last node: then you also hear when that workflow is unpublished or stops reaching the end.
If It Still Fails
No alert at all. Check in this order: you ran the workflow from the editor, it or Error Handler isn't published, its Error Workflow setting is empty, or the failed node is set to a Continue option.
The error workflow's executions show "tried to invoke this workflow to handle errors". n8n's caller policy blocked the call and saved that failed run instead. The default, workflowsFromSameOwner (workflow variables), only allows workflows from the same project. In Error Handler's settings, widen This workflow can be called by, for example with Selected workflows.
The alert node itself fails. A wrong SMTP password, a deleted Discord webhook or a wrong Chat ID fails the error workflow, and n8n won't run it again for its own failure. Give Error Handler its own published error workflow that alerts on a second channel: n8n only skips an error workflow that points at itself.
The link in the alert opens localhost:5678. n8n builds it from N8N_EDITOR_BASE_URL, then N8N_WEBHOOK_URL, then N8N_PROTOCOL, N8N_HOST and N8N_PORT, which default to http, localhost and 5678 (URL service, deployment variables). Set N8N_EDITOR_BASE_URL to your public address. Our reverse proxy guide covers the webhook side.
FAQ
Do I have to publish the error workflow? Yes, on n8n 2.x, and again after every change: n8n runs only its published version. The workflows it watches must be published too, because only production executions call it.
Why don't I get an alert when I test in the editor? Error workflows only run for automatic executions. Use the scheduled Stop And Error test from Step 3.
Does the free self-hosted edition show a failure rate?
Yes: the Insights banner on the Overview page shows failed production executions and the failure rate for the last 7 days on every edition. The full dashboard needs Business or Enterprise, and Log Streaming of n8n.workflow.failed events to a webhook, syslog or Sentry needs Enterprise.
How long does n8n keep failed executions?
By default until they're 336 hours (14 days) old or the total passes 10,000 executions, oldest first. Change that with EXECUTIONS_DATA_MAX_AGE (hours) and EXECUTIONS_DATA_PRUNE_MAX_COUNT, and keep the alerts as your long-term record.
Does Space-Node watch my n8n workflows? No. Our VPS plans are self-managed: you run n8n and its monitoring. If you need help managing the server, ask support about the scope before you order.
Sources
All opened on 30 and 31 October 2026:
- n8n docs: Handle errors gracefully, Error Trigger, Stop And Error, Configure workflow settings, Work with nodes, Types of executions, View all executions, Debug executions, Save and publish workflows, Schedule Trigger, HTTP Request, Expressions, Send Email, SMTP credentials, Discord, Discord credentials, Telegram message operations, Telegram credentials, Telegram common issues, Monitor n8n, Enable Prometheus metrics, Endpoint variables, Executions variables, Manage execution data, Log variables, Deployment variables, Workflow variables, Queue mode variables, Insights, Log streaming
- n8n source on GitHub: workflow-execute.ts, execute-error-workflow.ts, execution-lifecycle-hooks.ts, workflow-execution.service.ts, url.service.ts, event-bus-metrics.service.ts, message-event-bus.ts, Telegram GenericFunctions.ts, Discord webhook send, Discord node description, Send Email operation, editor UI strings
- n8n at the 2.45.7 release: workflow-execution.service.ts, WorkflowSettings.vue, pull request 22019 (error workflows must be published)
- Uptime Kuma on GitHub: README, api-router.js, monitor.js, EditMonitor.vue
- Discord: Webhook resource, Telegram Bot API
- Docker docs: docker compose up, docker compose logs, Compose services
- nginx: ngx_http_access_module, ngx_http_core_module, command-line parameters