n8n error handling works in three layers: Retry On Fail reruns a failed node up to 5 times with at most 5 seconds between tries, On Error decides whether a lasting failure stops the run or goes down a separate error output, and an error workflow that starts with the Error Trigger alerts you whenever a production execution fails. This guide gives you an import-ready Slack alert workflow with the execution link, a retry-settings table per node type, and a backoff loop for outages longer than 20 seconds.
n8n error handling that holds up in production means three things: Retry On Fail on nodes that call outside services, an On Error choice on every node that can fail, and one error workflow, started by the Error Trigger node, that alerts you with a link to the failed execution. Retries absorb blips, error outputs keep one bad item from killing a batch, and the error workflow makes sure no failure goes unnoticed.
Checked October 2026 against n8n's docs on the Error Trigger, node settings, error handling and executions, and the source code of n8n 2.41.4. This version replaces the January 2025 article, whose retry settings exceeded n8n's limits.
This guide is part of our n8n hub, which collects templates, integrations and self-hosting guides. Everything below is the setup we put on every workflow that runs on a schedule or a webhook: two import-ready workflow files, the retry defaults we use per node type, and the checks that catch the failures an error workflow cannot see.
How n8n error handling works
n8n gives you controls at the node, the workflow and the instance level. They are meant to be stacked, not chosen between. A failed node first retries; if it still fails, its On Error setting decides what happens; if the run fails, the error workflow fires.
- 01Node fails
Timeout, 429, 5xx, bad data or a thrown error.
- 02Retry On Fail
Up to 5 tries, up to 5 seconds apart.
- 03On Error
Stop the run, continue, or send the item to an error output.
- 04Execution fails
Saved with status Failed in the Executions list.
- 05Error workflow
Error Trigger receives the details and posts a Slack alert with the link.
| Control | Where you set it | What it does |
|---|---|---|
| Retry On Fail | Node > Settings | Reruns a failed node: 2 to 5 tries, up to 5 seconds apart |
| On Error | Node > Settings | Stop Workflow (default), Continue, or Continue (using error output) |
| Stop And Error node | On the canvas | Fails the execution on purpose with your own message |
| Error workflow | Workflow > Settings > Error Workflow | Runs a workflow that starts with the Error Trigger whenever a production execution fails |
| Executions list | Executions tab | Filter failed runs, debug them in the editor and retry them |
How do you build an n8n error workflow with Slack alerts?
- 1Create the handler
New workflow with the Error Trigger as its first node. Name it Error Handler. It does not need to be published.
- 2Normalise the payload
A Code node turns execution failures and trigger failures into the same fields.
- 3Send the alert
Slack, Gmail, Teams or Telegram, with the workflow name, node, error and execution link.
- 4Point every workflow at it
Workflow menu, Settings, Error Workflow. One handler can serve all of them.
- 5Keep failed runs saved
Leave Save failed production executions on, or the alert has no link.
Two behaviours catch people out. Error workflows run only for production executions started by a schedule, webhook or app event, never for manual test runs. And a workflow that contains an Error Trigger uses itself as its error workflow by default. Both are in the Error Trigger docs.
What the Error Trigger receives
For a failed execution, the Error Trigger outputs this (n8n's documented 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" }
}
]execution.idandexecution.urlexist only if the execution was saved.execution.retryOfappears only when the failed run was itself a retry, which is useful for muting repeat alerts.- If the main workflow's trigger node failed, for example when a trigger could not activate, the details arrive under
triggerinstead ofexecution.
Copy-paste error workflow JSON
Copy this, open a blank workflow in n8n and paste it onto the canvas. You get the Error Trigger, a Code node that normalises both payload shapes, and a Slack node that posts to #n8n-alerts with the execution link. Select your Slack credential, change the channel, save, then select this workflow in the Settings of each workflow you want to protect.
{
"name": "Error Handler (Slack alert)",
"nodes": [
{
"parameters": {},
"id": "a1f6c1e2-0001-4c6b-9e1a-000000000001",
"name": "Error Trigger",
"type": "n8n-nodes-base.errorTrigger",
"typeVersion": 1,
"position": [
0,
0
]
},
{
"parameters": {
"jsCode": "const data = $input.first().json;\nconst execution = data.execution ?? {};\nconst trigger = data.trigger ?? {};\n\nreturn [{\n json: {\n workflowName: data.workflow?.name || 'Unnamed workflow',\n failedNode: execution.lastNodeExecuted ?? 'Trigger',\n message: execution.error?.message ?? trigger.error?.message ?? 'No error message',\n mode: execution.mode ?? trigger.mode ?? '',\n executionUrl: execution.url ?? '',\n isRetry: Boolean(execution.retryOf),\n },\n}];"
},
"id": "a1f6c1e2-0002-4c6b-9e1a-000000000002",
"name": "Normalise error",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
220,
0
]
},
{
"parameters": {
"select": "channel",
"channelId": {
"__rl": true,
"mode": "name",
"value": "#n8n-alerts"
},
"text": "=:rotating_light: *{{ $json.workflowName }}* failed\nNode: {{ $json.failedNode }}\nError: {{ $json.message }}\nMode: {{ $json.mode }}{{ $json.isRetry ? ' (this run was a retry)' : '' }}\nOpen and retry: {{ $json.executionUrl }}",
"otherOptions": {}
},
"id": "a1f6c1e2-0003-4c6b-9e1a-000000000003",
"name": "Slack alert",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [
440,
0
],
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 2000
}
],
"connections": {
"Error Trigger": {
"main": [
[
{
"node": "Normalise error",
"type": "main",
"index": 0
}
]
]
},
"Normalise error": {
"main": [
[
{
"node": "Slack alert",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
}
}The Slack node retries itself three times, two seconds apart, because a missed alert is the one failure you will never hear about. To test without breaking anything, open the Error Trigger and select Execute step: in a manual run it outputs sample data like the example above. On self-hosted n8n the execution link is built from N8N_EDITOR_BASE_URL, or the webhook URL if that is not set (see the error workflow source). If your alerts link to localhost, set it to the address you open n8n on.
Error workflow runs are free to add: n8n's executions docs list them, with manual and sub-workflow runs, among those that do not count toward a paid plan's quota. Our n8n pricing guide explains what does count.
How does n8n retry on fail work, and what should you set?
Open a node, select Settings and turn on Retry On Fail. Two fields appear:
- Max. Tries: total attempts, from 2 to 5 (default 3).
- Wait Between Tries (ms): a fixed pause from 0 to 5,000 milliseconds (default 1,000).
- Max. Tries is clamped to 2 to 5
- Wait Between Tries is clamped to 0 to 5,000 ms
- The wait is fixed; there is no built-in backoff
Source: n8n 2.41.4 source, getRetryParams in workflow-execute.ts
The engine clamps any other value to those ranges (see getRetryParams in workflow-execute.ts). One quirk in that code: a wait of 0 is treated as empty and falls back to the 1,000 ms default, so you cannot retry instantly. Neither field accepts expressions.
These are the defaults we start from. They are our working settings, not n8n recommendations; tune them to each API's documented rate limits.
| Node type | Retry On Fail | Max. Tries | Wait (ms) | On Error | Why |
|---|---|---|---|---|---|
| HTTP Request, read (GET) | On | 3 | 2,000 | Stop Workflow | Safe to repeat; covers timeouts and 502/503/504 |
| HTTP Request, write (POST) | Only with an idempotency key | 2 | 5,000 | Continue (using error output) | A retry after a timeout can create the record twice |
| OpenAI, Anthropic or Gemini model call | On | 3 | 5,000 | Stop Workflow | Rate limits and overloaded responses usually clear within seconds |
| Google Sheets append | On | 2 | 5,000 | Continue (using error output) | Quota errors are common; log the row instead of losing it |
| Postgres or Supabase insert | On, with upsert | 2 | 1,000 | Stop Workflow | Connection drops recover fast; constraint errors never will |
| Slack, email or Telegram alert | On | 3 | 2,000 | Continue | A failed notification should not fail the business run |
| Code node | Off | - | - | Stop Workflow | Its errors are deterministic; a retry fails the same way |
| Respond to Webhook | Off | - | - | Stop Workflow | The caller has already timed out by the time a retry lands |
Retry timeouts, dropped connections, 429 and 5xx responses. Do not retry 400, 404 or 422 validation errors, or 401 and 403 credential errors: fix the data or the credential instead. For 429s, n8n's rate-limit guide shows two ways to slow down: Loop Over Items with a Wait node, or the HTTP Request node's Batching option. Be careful with steps that create things. If an API times out after it has already created an order or sent an email, a retry does it twice, so use the API's idempotency key or look up the record before creating it.
Decide what a failure does with On Error
When a node still fails after its retries, its On Error setting decides what happens next:
| Option | What happens | Error workflow runs? |
|---|---|---|
| Stop Workflow (default) | The execution stops and is marked as failed | Yes |
| Continue | The workflow keeps going, and the error is passed along in the node's regular output | Not for this node |
| Continue (using error output) | Successful items leave through the success output, failed items through a second error output | Not for this node |
The error output suits batches, because one bad record no longer stops the other 99. Items on the error branch keep the fields of the input item that failed, plus the error details, so you can write them to a Data Table or spreadsheet for review. If a failed item should still count as a failed run, end that branch with a Stop And Error node so the execution fails and your error workflow fires.
Fail on purpose with Stop And Error
Some problems are not errors to n8n: an order without an email address, a total of zero, an empty API response. Catch them with an If node and send the bad branch to a Stop And Error node. Choose Error Message (text that can include expressions, for example Order {{ $json.orderId }} has no customer email) or Error Object (a JSON object with the properties you want). The execution fails and your error workflow receives the message as execution.error.message. This turns silent data problems into alerts.
The retry path: exponential backoff with a Wait loop
When an API needs more than 20 seconds to recover, build the backoff yourself. Turn Retry On Fail off on the calling node, set its On Error to Continue (using error output), and loop the error output through a Code node and a Wait node back into the same node. Use this only for calls that are safe to repeat. Paste this skeleton, then replace the Manual Trigger and the URL with your own:
{
"name": "Retry path with exponential backoff",
"nodes": [
{
"parameters": {},
"id": "b2e7d2f3-0001-4d7c-8f2b-000000000001",
"name": "Manual Trigger",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
0,
0
]
},
{
"parameters": {
"url": "https://api.example.com/orders",
"options": {}
},
"id": "b2e7d2f3-0002-4d7c-8f2b-000000000002",
"name": "Call API",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
220,
0
],
"onError": "continueErrorOutput"
},
{
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const item = $input.item.json;\nconst attempt = (item.attempt ?? 0) + 1;\n\nif (attempt > 5) {\n // Throwing fails the execution, so the error workflow runs\n throw new Error('Gave up after 5 retries: ' + JSON.stringify(item.error));\n}\n\n// Waits of 2, 4, 8, 16 and 32 seconds, plus up to 2 seconds of jitter\nconst waitSeconds = 2 ** attempt + Math.floor(Math.random() * 3);\n\nreturn { json: { ...item, attempt, waitSeconds } };"
},
"id": "b2e7d2f3-0003-4d7c-8f2b-000000000003",
"name": "Backoff",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
440,
160
]
},
{
"parameters": {
"amount": "={{ $json.waitSeconds }}",
"unit": "seconds"
},
"id": "b2e7d2f3-0004-4d7c-8f2b-000000000004",
"name": "Wait",
"type": "n8n-nodes-base.wait",
"typeVersion": 1.1,
"position": [
660,
160
],
"webhookId": "b2e7d2f3-0005-4d7c-8f2b-000000000005"
}
],
"connections": {
"Manual Trigger": {
"main": [
[
{
"node": "Call API",
"type": "main",
"index": 0
}
]
]
},
"Call API": {
"main": [
[],
[
{
"node": "Backoff",
"type": "main",
"index": 0
}
]
]
},
"Backoff": {
"main": [
[
{
"node": "Wait",
"type": "main",
"index": 0
}
]
]
},
"Wait": {
"main": [
[
{
"node": "Call API",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
}
}Each failed item carries its attempt count around the loop. After the fifth attempt the Code node throws, the execution fails, and the error workflow above sends the alert with the last error attached. The jitter spreads retries out when many items fail at once. According to the Wait node docs, waits shorter than 65 seconds keep the execution in memory, while longer waits are saved to the database until they resume.
If you are wiring this around a client API, our guides to connecting any API in n8n and CRM automation show the request side.
Find, debug and re-run failed executions
- Find them: open the workflow's Executions tab and filter Status by Failed. The overall executions list does the same across workflows.
- Debug them: select a failed execution and choose Debug in editor. n8n copies its data into the editor and pins it to the first node, so you can fix the workflow and rerun it on the same input. The debug docs list this on all Cloud plans and on self-hosted Registered Community, Business and Enterprise.
- Retry them: the retry icon on a failed execution offers Retry with currently saved workflow or Retry with original workflow, both using the failed run's data. This is the manual retry path the Slack link leads to.
- Keep them long enough: self-hosted n8n prunes finished executions older than 336 hours (14 days) or beyond 10,000 executions by default. Change that with
EXECUTIONS_DATA_MAX_AGEandEXECUTIONS_DATA_PRUNE_MAX_COUNT, per n8n's execution data guide. - Make them searchable: the Execution Data node saves fields such as an order ID that you can filter by later. It needs Cloud Pro or Enterprise, or self-hosted Registered Community or Enterprise.
Watch the instance, not only the workflows
An error workflow cannot run if n8n itself is down, and on Cloud a run blocked by your execution limit fails before any node runs. Add checks from outside, as described in n8n's monitoring docs:
- Point an uptime monitor at
/healthz, which returns 200 when the instance is reachable, or/healthz/readiness, which also confirms the database is connected and migrated. Self-hosted instances can expose Prometheus metrics at/metrics. - Send yourself a daily digest: a scheduled workflow using the n8n node's Execution, Get Many operation, filtered to failed runs. It relies on the n8n API, which is not available on the Cloud free trial.
- On Enterprise plans, log streaming sends n8n's events to your own logging tools.
Self-hosting adds its own failure modes, from a full disk to a container that restarts without its environment variables. Our n8n self-hosting guide covers the setup that avoids most of them.
Errors in AI agent tools
When a node runs as a tool for the AI Agent node, n8n's execution engine returns the error to the agent as the tool's response by default instead of failing the run, so the model can try again or explain the problem. If a failed tool call must stop the execution, set that tool node's On Error to Stop Workflow; the engine respects that explicit choice. For the model-call side of an agent, see our guide to integrating GPT with n8n.
n8n error handling checklist for production
- Error Workflow set in Settings to your shared handler
- Save failed production executions turned on
- Retry On Fail on every node that calls an outside service and is safe to repeat
- Error outputs on batch steps, ending in Stop And Error where a failure must stay visible
- Stop And Error after checks for missing or invalid data
- Idempotency key or lookup before any create, send or charge step
- Execution retention long enough to debug last week's problem
- An outside uptime check on /healthz
If you are hardening automations because they are turning into a product, our AI SaaS Builder program covers the same discipline for Claude API features in a Next.js app: retries, rate limits, fallbacks and the billing around them.
n8n error handling: FAQ
How do I handle errors in n8n?
Use three layers. Turn on Retry On Fail in a node's Settings for temporary failures, set the node's On Error option to stop, continue or route failed items to an error output, and give every production workflow an error workflow that starts with the Error Trigger node, so a failed execution sends you an alert. Choose the error workflow in each workflow's Settings under Error Workflow.
Why is my n8n error workflow not running?
Error workflows run only for automatic (production) executions, not for manual test runs. Check that the failing workflow is published, that its Settings name your error workflow, and that the failing node is not set to Continue, because a node that continues does not fail the execution. To build the alert without a real failure, run the Error Trigger step on its own: it outputs sample error data.
How many times can Retry On Fail retry in n8n?
Max. Tries accepts 2 to 5 attempts (default 3) and Wait Between Tries accepts 0 to 5,000 milliseconds (default 1,000). n8n's execution engine clamps values outside those ranges, so one node retries for about 20 seconds at most. The wait is the same before every attempt. For longer or growing delays, loop failed items through a Wait node instead.
What is the difference between Continue and Continue (using error output) in n8n?
Continue passes the error along in the node's regular output, so the next nodes receive it like normal data and the run is not marked as failed. Continue (using error output) gives the node a second output: successful items leave through the success output and failed items through the error output, so you can retry, log or alert on them in their own branch.
What data does the n8n Error Trigger receive?
For a failed execution it receives execution.id, execution.url, execution.error with message and stack, execution.lastNodeExecuted, execution.mode, execution.retryOf when the run was itself a retry, and workflow.id and workflow.name. The ID and URL exist only if the execution was saved. If the main workflow's trigger node failed, the details arrive under trigger instead of execution.
Do error workflow runs count toward n8n execution limits?
No. n8n's documentation lists error workflow executions, manual executions and sub-workflow executions among the runs that do not count toward a paid plan's execution quota, and failed executions do not count either. An error workflow that alerts on every failure therefore costs nothing extra on Cloud plans. Checked October 2026.
How do I make an n8n workflow fail on purpose?
Add a Stop And Error node where the run should stop, usually on the true branch of an If node that checks the data, such as an order without an email address. Choose Error Message or Error Object. The execution fails with your message, and your error workflow receives it as execution.error.message, so a silent data problem becomes an alert.
Automations that keep running. Products that keep earning their place.
AI SaaS Builder, included in All Access, covers n8n in production, the Claude API and shipping a paid AI product, with the other three programs, live coaching and the private community in one subscription.
Stuck on a failing workflow?
Bring the error message to the free Discord, where members share n8n fixes and workflows, or start from a working template in our library post.