n8n Stop and Error node: failing a workflow on purpose (complete guide)
Published 26 August 2026 · 8 min read
A workflow that finishes "successfully" after storing an invoice with no amount is far more dangerous than one that crashes: the first quietly fills your database with rubbish for three weeks, the second alerts you within a minute. The Stop and Error node (n8n-nodes-base.stopAndError) turns an invalid business condition into an explicit failure, visible in the executions list and caught by the Error Workflow. This guide covers its two modes, the patterns where it is indispensable, the ones where it adds nothing, and the classic traps.
Fail fast rather than corrupt slowly
The natural reflex, when malformed data arrives, is to route around it: an IF, an empty branch, move on. But the empty branch leaves no trace. The execution stays green, and the day someone notices that a quarter of the records never went out, you are digging through weeks of history.
The software reliability literature is unambiguous. In "Simple Testing Can Prevent Most Critical Failures: An Analysis of Production Failures in Distributed Data-Intensive Systems", presented at OSDI 2014 by Ding Yuan, Yu Luo, Xin Zhuang, Michael Stumm and co-authors, an analysis of 198 real-world failures across Cassandra, HBase, HDFS, Hadoop MapReduce and Redis found that 92% of catastrophic failures stem from incorrect handling of non-fatal errors that the software had already signalled (see on Google Scholar). The information was there; someone swallowed it. Stop and Error is the tool that prevents that scenario in n8n.
What the node actually does
Stop and Error interrupts the execution and marks it as failed. Two consequences: it has no output (no node can be wired downstream, so it is always the last node on its branch), and the run counts as a failure, just like an HTTP timeout, with its red line in the executions list. The main parameter, Error Type, offers two values.
Error Message: the plain string
The Error Message field takes text and accepts n8n expressions. That is the whole point: the message should carry the offending data, not a platitude.
Invalid email for contact {{ $json.id }}: "{{ $json.email }}" — CRM import aborted
A message like that reads straight from the Slack alert, without opening n8n; compare it with "Validation error". For expression syntax and reaching back into earlier nodes via $('Node').item.json, see the JavaScript expressions guide.
Error Object: structured context
The Error Object field takes a JSON object: its message field supplies the error message, the other properties carry context that downstream logic can use.
{
"message": "API response missing invoice_id field",
"code": "MISSING_INVOICE_ID",
"record_id": "{{ $json.id }}",
"http_status": "{{ $json.statusCode }}"
}
The object wins as soon as the Error Workflow has to decide rather than display. With a stable business code, it routes: MISSING_INVOICE_ID to finance, QUOTA_EXCEEDED to the on-call engineer. A text message forces you to pattern-match on a string — fragile the moment someone rewords it.
What happens immediately afterwards
The error follows the same path as an error you suffered. If an Error Workflow is configured in the Settings, n8n triggers it and its Error Trigger node receives the usual object:
$json.execution.error.message— your message, or themessagefield of your object;$json.execution.lastNodeExecuted— the name of your Stop and Error node, hence the importance of renaming it:Stop and Error1says nothing,Reject — invalid emailsays everything;$json.execution.idand$json.execution.url, for a direct link to the run;$json.workflow.idand$json.workflow.name.
The full circuit — Retry On Fail, the On Error setting, Error Trigger and Slack alerting — is covered in the guide to error handling. Stop and Error is only its deliberate source: without that circuit, you are manufacturing red executions nobody watches.
Pattern 1: the validation guard rail
This is the canonical use. An IF or Switch node tests the business condition — {{ $json.email }} is not empty, {{ $json.amount }} larger than 0 — the true output continues the pipeline, the false output ends on a Stop and Error naming the record id and the offending value.
What this buys over plain filtering is visibility: an item dropped by a Filter vanishes silently, an item hitting a Stop and Error produces a red execution, a notification and a line in the history. The choice is not technical, it is contractual: is invalid data normal here (there are always blank rows in an export) or abnormal (the supplier committed to a schema)? In the first case, Filter is enough; in the second, failing is the correct answer.
Pattern 2: the post-condition after an external call
The second use is less obvious and more valuable: checking after a call that you got what you asked for. An API returning 200 OK with an empty body, a model answering in prose instead of the requested JSON, a partner webhook silently renaming a field — none of these raise an HTTP error, and the next node writes undefined to the database.
An IF on {{ $json.data?.invoice_id }} is not empty followed by a Stop and Error turns that undefined into a clean failure, at the exact point of the anomaly. It is the counterpart to the guard rails covered in the guide to HTTP Request retries and timeouts: retries protect you from the call that fails, post-conditions from the call that "succeeds" badly. On AI chains, where malformed output dominates, the article on AI Agent node errors details the checks worth adding.
The sub-workflow case
An error raised inside a sub-workflow propagates to the parent workflow, provided the Execute Sub-workflow node's Wait for Sub-Workflow Completion option is on — the default. The parent fails in turn and it is its Error Workflow that fires. Switch that wait off for fire-and-forget behaviour and the failure stays confined to the sub-workflow: decoupling that is sometimes deliberate, rarely so when the parent depends on the result (see splitting workflows into sub-workflows). A Stop and Error inside a shared validation sub-workflow then becomes a reusable assertion: one "validate a contact" workflow, called by five pipelines, failing the same way everywhere.
When NOT to use it
- When an ignore branch is enough: three blank rows in a 4,000-line CSV are not an incident. A Filter, or a NoOp at the end of the branch, keeps the run green and the batch complete.
- When the error is expected and recoverable: an occasional 429 is handled with Retry On Fail. For a missing record you can create on the fly, the On Error → Continue (using error output) setting opens a second output to wire the recovery onto.
- When it only pollutes your statistics: a workflow that is 30% red by design alerts nobody. If your Stop and Error fires every day, it is no longer an exception, it is a nominal case that was modelled badly.
The question is an old one. Zongwei Luo, Amit Sheth, Krys Kochut and John Miller addressed it back in 2000 in "Exception Handling in Workflow Systems", published in Applied Intelligence (vol. 13, pp. 125-147), : they separate system exceptions, which the engine absorbs on its own, from user-defined exceptions written into the process model, and stress that human involvement stays decisive for situations an engine cannot resolve by itself (see on Google Scholar). Stop and Error exists precisely to force that handover to a human; used for what a retry or a filter handles perfectly well, it only manufactures noise.
Alternatives and companions
| Need | Tool |
|---|---|
| Drop an item without failing | Filter node, or a NoOp branch |
| Handle a node failure inside the flow | On Error → Continue (using error output) |
| Absorb a transient outage | Retry On Fail (Max Tries, Wait Between Tries) |
| Raise an error from code | throw new Error('…') in a Code node |
| React to a workflow failure | Error Trigger + Error Workflow |
| Trace without failing | Execution Data node |
throw new Error() in a Code node does the same job, but it is invisible on the canvas: for a business rule other people need to see, the dedicated node wins. And when a condition deserves a trace without failing, the Execution Data node tags the run with searchable keys — a warning without the red.
The classic traps
- The useless message: "Error", "KO", "Invalid data" force you to reopen the execution. A message should carry the record id, the offending value and the rule violated — that is debugging you get to skip.
- Stop and Error inside a loop: hit on the third item of a five-hundred item batch, it kills the whole run. If the invalidity is per-item, drop the item; if it invalidates the batch, validate before the loop.
- Webhook-triggered workflows: failing returns an error response to the caller instead of the expected 200 — sometimes exactly what you want, sometimes enough to break a partner that retries in a loop. The Respond to Webhook node lets you return a controlled status and body.
- Side effects already committed: the node halts what comes next, it rolls nothing back. Three rows inserted and two emails sent stay sent, so a replay after fixing the data has to be safe — that is the business of idempotency.
- The unrenamed node:
lastNodeExecutedsurfaces its name, and five genericStop and Errornodes produce five indistinguishable alerts. - The rule nobody tested: a guard rail that never fires in testing is only a hypothesis. Validating in CI against a deliberately broken dataset confirms that the invalid branch really goes where you think.
Key takeaways
Two parameters only — Error Type as Error Message or Error Object, plus the matching content — but above all a design decision. Fail when the data breaches a contract someone committed to, and let Filter do the work when the anomaly is part of daily life. Write messages that carry the offending data, move to Error Object as soon as the Error Workflow needs to route on a code, rename the node: an explicit failure is only worth as much as the alerting circuit that catches it.
Going further
Validation guard rails matter most where bad data has lasting consequences. The Compliance & Audit Pack (€149) applies that reasoning to traceable processing: completeness checks before writing, explicit failures and an incident log you can actually use. For email processing where every message must produce a verifiable result before reaching the CRM, the AI Inbox Pack (€79) applies the same post-conditions to model outputs.
FAQ
Frequently asked questions
How do I make an n8n workflow fail on purpose?
Place a Stop and Error node at the end of the branch concerned. It halts the execution and marks it as failed, exactly as if a node had crashed. The node has no output connector: nothing can be wired after it, so it is always the last node on its branch. Then pick the Error Type parameter between Error Message, which takes text enriched with expressions, and Error Object, which takes a JSON object. The run shows up in red in the executions list and triggers the workflow's Error Workflow.
What is the difference between Error Message and Error Object?
Error Message expects a plain string, into which you can inject expressions such as {{ $json.email }} to make the message diagnosable. Error Object expects a JSON object whose message field supplies the error message, the remaining properties carrying structured context: a business code, the offending record id, the step involved. The object wins as soon as the Error Workflow has to route or filter on the nature of the error rather than simply display it.
Does Stop and Error trigger the Error Workflow?
Yes. An error raised by Stop and Error is treated like any other execution failure: n8n runs the workflow named in the Error Workflow setting, and its Error Trigger node receives the usual object with execution.error.message, execution.lastNodeExecuted, execution.id and workflow.name. The lastNodeExecuted field holds the name of your Stop and Error node, so rename it explicitly or every alert you get will look the same.
Can I use Stop and Error inside a loop?
You can, but you rarely should. A Stop and Error reached on the third item of a five-hundred item batch aborts the whole execution: the remaining items are never processed, and those already handled have left side effects behind. To drop an invalid item without killing the batch, prefer a Filter node, or the On Error setting with Continue Using Error Output on the fragile node, then aggregate the rejects and report them at the end.
Bundle FlowKit Complet
€269