Sparround

Error handling and the error workflow

Every workflow touching external systems will fail at some point. The question is not whether it fails but who learns about it, and when.

Error handling in n8n is built at three levels:

  • Node level — retries, and how the node behaves when it errors
  • Workflow level — an error workflow set in Workflow Settings
  • Logical level — failing an execution deliberately on your own condition with the Stop And Error node

An error workflow is a separate workflow that must start with the Error Trigger node. It runs when the main workflow's execution fails. One error workflow can serve many workflows — which is exactly how centralised alerting is built in practice.

json
[
  {
    "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"
    }
  }
]

The default payload the Error Trigger receives. `execution.id` and `execution.url` require the execution to be saved in the database; `retryOf` appears only on retries.

An important nuance: if the failure happened in the main workflow's trigger node, the payload reaching the error workflow is different — execution{} carries less and a trigger{} object appears instead. The reason is simple: the workflow never really executed.

Keep that in mind when writing an error workflow: assuming execution.url is always present is a mistake.

Retrying does not suit every error. Treat it as meaningful only for transient failures:

  • 429, 5xx, network errors, timeouts → retrying makes sense
  • 400, 401, 403, 404 → retrying is pointless; the request, the credential or the resource is wrong

Sending a bad request three times does not fix it — it only delays the moment the failure becomes visible.

SituationThe right behaviour
3 of 100 records failContinue-on-error at node level — route failures down a separate path and report at the end
The API is temporarily unavailableNode-level retry with an interval between attempts
The credential has expiredDo not retry — alert immediately; this needs a person
The incoming data is not in the expected shapeValidate early with an IF; stop with a clear message using Stop And Error
The whole process has stoppedImmediate alert from the error workflow: which workflow, which node, the execution link

Silent failure is the worst outcome. The workflow breaks, nobody knows, and two weeks later somebody asks "why is this data stale?". So setting an error workflow on every production workflow is the minimum bar — build it once and attach it everywhere.

📚 Sources and documentation