Retrying a failed n8n run is not retrying the operation
The retry menu resumes from the node that failed, which is why it skips the check you wrote to stop a second payment going out. In these threads the duplicates mostly come from a fresh run, not from that button. Here is what each retry mechanism does.
Two calls went through, the third failed, and now what?
The question comes up in the same shape every time:
The first two API calls succeed, but the third one fails. The problem is that if I simply retry the entire workflow, the first two APIs are called again, which could create duplicate actions.
- a user, Partial failures when an n8n workflow calls multiple APIs, n8n Community, 30 August 2026
And its nastier cousin, where the failure is not even real:
sometimes the external API times out after actually processing the request. n8n sees the timeout as a failure and retries the execution, which can cause the same operation to be processed twice.
- a user, Duplicate Processing When an n8n Workflow Is Retried, n8n Community, 3 September 2026
Someone in the first thread drew the distinction the documentation does not: "retrying an execution and retrying a business operation are two very different things", wrote one user on 1 September. Everything below follows from that.
What does the retry button actually do?
More than the documentation admits. Open the executions list, click the menu on a failed run, and n8n offers two options whose full labels read "Retry with currently saved workflow (from node with error)" and "Retry with original workflow (from node with error)".
That parenthesis is in the product. It is not in the documentation, which describes both options only as running the workflow "with the previous execution data" and never uses the word resume, never says which node the run continues from, and never mentions that some executions cannot be retried at all.
The engine backs the label up: when a node fails and the workflow is set to stop, n8n pushes that node back onto the execution stack specifically so the run can be restarted from it. A retry clears the recorded error on the last executed node and lets the stack decide what runs next.
So the popular belief that n8n always replays a failed run from the very first node is wrong. What the retry does is skip everything that already succeeded, which is a different problem and the one worth understanding.
Which is exactly why it skips your guard
If you built a check at the top of the workflow that asks "have we already processed this event", a retry from the failed node walks straight past it. The check already ran. It succeeded. It is not going to run again.
One smaller thing on manual retries: retrying from the start replays the claim as designed, but retrying from the failed node skips it entirely, so the state machine never sees the second attempt.
- a user, How to make an n8n lead-intake workflow safe to retry without creating duplicates, n8n Community, 18 August 2026
The same person flags a second way a guard becomes decorative, this time from a node setting rather than a retry: with On Error set to continue using the error output, "the execution stays green, control walks past the branch you wrote to catch duplicates, and the CRM write happens anyway".
When can you not retry at all?
Three cases, enforced in the code rather than described in the docs. An execution aborted before it started cannot be retried. One still queued and not yet started cannot be retried. And a successful execution cannot be retried, which matters more than it sounds: if the run finished green while doing the wrong thing, the retry button is not the tool.
Where do the duplicates actually come from?
In these threads, mostly from a second run rather than from the retry button. The external API times out after doing the work and the caller tries again. A webhook is delivered twice. Or a node-level retry quietly runs its own attempts inside a run you thought you were controlling:
Turn off retryOnFail on the API node. Node level retries re-run inside the same execution and will happily bypass logic you have wrapped around the node.
- a responder, Duplicate Processing When an n8n Workflow Is Retried, n8n Community, 4 September 2026
A forum moderator describes the same collision from the accounting side:
Retry On Fail reruns the node inside the same execution, so those attempts all finish before Update PostgreSQL runs and
attemptsnever increments. The queue has no record the request went out, which is how the same customer gets sent twice. Run one retry layer, not two.
- a community moderator, Handle API rate limits and retries in n8n without creating duplicate requests, n8n Community, 20 August 2026
Which retry re-runs what
Three different mechanisms get called "retry", and they behave differently:
| Mechanism | What re-runs | Does it re-run your duplicate guard? |
|---|---|---|
| Retry from the executions list | The run continues from the node that failed | No. Nodes that already succeeded are not run again |
| Retry On Fail on a node | That one node, inside the same execution | No. Nothing outside the node is involved |
| A fresh run of the workflow | Everything, from the trigger | Yes, which is why the guard has to be able to say no |
The third row is the one that saves you, and only if the guard consults something that outlives the execution.
Retry On Fail has limits that nobody writes down
n8n's node settings page says only this:
Retry On Fail: When an execution fails, the node reruns until it succeeds.
- Work with nodes, n8n Docs
"Until it succeeds" is not what happens, and the page names neither of the two parameters that govern it. In the engine, checked against n8n's main branch in September 2026, the values you type are clamped: max tries is held between two and five, defaulting to three, and the wait between tries is held between zero and five thousand milliseconds, defaulting to one second.
Type fifty tries and you get five. Type a thirty-second pause to ride out a rate limit and you get five seconds. That is worth knowing before you build a backoff strategy on a setting that silently caps itself.
The goal is not to run exactly once
Nobody achieves exactly-once against a network. The person who opened one of these threads put the target better than the documentation does:
The useful goal is not "run exactly once." It is: the same logical event can be processed again without creating an additional business action.
- a responder, How to make an n8n lead-intake workflow safe to retry without creating duplicates, n8n Community, 17 August 2026
That reframing is what makes the rest tractable. You are not trying to prevent a second execution. You are trying to make a second execution harmless.
Why a checkpoint written after success does not help
The obvious design is to record "done" after each step and skip completed steps on the next run. It leaves a hole exactly where the failures live:
Insert/upsert
state = preparedbefore the API call, with a stableoperation_keysuch asorder:123:payment. [...] A checkpoint written only after success cannot close that window.
- a responder, Partial failures when an n8n workflow calls multiple APIs, n8n Community, 3 September 2026
Write the intention before you act, not the result after. Then a retry finds a row that says "we were about to charge this card" and can go and ask what happened, instead of finding nothing and assuming nothing happened.
Two failure modes to design for while you are in there, both from people who have been bitten:
if two retries arrive close together, both can pass the status check before either has processed, and then both process. The unique index stops a second row, it does not stop a second API call.
A plain ON CONFLICT DO NOTHING marks the row 'processing' and never releases it, so the exact crash you are asking about leaves that row 'processing' forever. [...] That is usually worse than a duplicate, because nothing alerts you.
- the same responder, Duplicate Processing When an n8n Workflow Is Retried, n8n Community, 4 September 2026
The remedy for the second one, from the same set of threads, is a claim timestamp plus a sweep: record when a row was claimed, and have something reclaim rows older than your realistic maximum execution time. Without it you trade loud duplicates for silent stuck records, which is a bad trade.
Let the other side deduplicate, when it offers to
The cleanest fix is not in n8n at all. If the API you are calling supports idempotency keys, the duplicate problem moves to a system designed for it. Stripe documents the behaviour precisely:
Stripe's idempotency works by saving the resulting status code and body of the first request made for any given idempotency key, regardless of whether it succeeds or fails. Subsequent requests with the same key return the same result, including 500 errors.
- Idempotent requests, Stripe API documentation
Two clauses on that page decide how you build the key. It has a shelf life:
You can remove keys from the system automatically after they're at least 24 hours old. We generate a new request if a key is reused after the original is pruned. The idempotency layer compares incoming parameters to those of the original request and errors if they're not the same to prevent accidental misuse.
- same page, Stripe API documentation
So the key has to be stored with your record and reused, whether it is derived from the order id or a generated identifier you keep. A key generated fresh on each run defeats the mechanism, because the retry sends a different one. Stripe also asks you to keep personal data out of keys, and notes that all POST requests accept them while GET and DELETE do not need them.
Every vendor's rules differ, which is the point: read the page for the specific API before building your own deduplication layer around it.
n8n does have a deduplication node
For the cases where the other side offers nothing, there is a built-in option that many people never find. The Remove Duplicates node has an operation for removing items processed in previous executions, with a "Keep Items Where" setting:
Value Is New: n8n removes items if their value matches items from earlier executions.
History Size: The number of items for n8n to store to track duplicates across executions. [...] By default, n8n stores 10,000 items.
- Remove Duplicates, n8n Docs
Useful, with a boundary worth stating plainly: it filters items arriving at a node. It knows nothing about whether a side effect reached the outside world, and its memory is finite. It is a good guard against reprocessing the same input twice. It is not a substitute for an idempotency key on a payment.
One thing that will not help, in case you were planning on it: pinned data is a development tool. The documentation is explicit that production executions ignore all pinned data, so you cannot use it to skip work in a live run.
The failure this whole conversation misses
Everything above is triggered by something failing. One person in these threads pointed at the case that is not:
Everything in this thread is triggered by a failure. [...] That leaves one case uncovered, and it is the one that actually loses data quietly: the run that does not fail.
- a user, Handle Failed n8n Workflows Without Losing Data, n8n Community, 10 August 2026
Their example is a stray filter in a Code node cutting eight correct rows to zero, with the run reporting success either way, because "Completed with 8 of 8" and "completed with 0 of 8" are different outcomes sharing a status.
The other gap in the same thread is worth knowing if you rely on an error workflow: it only runs if n8n is alive to run it. A container that gets killed mid-execution fires nothing at all, and the job sits at processing forever.
An order of operations that survives retries
- Decide what a duplicate means for this workflow. A second email is annoying. A second payment is a refund and an apology. The effort should match.
- Check whether the API supports idempotency keys, and use a deterministic key built from your own identifier if it does. This is the cheapest fix available.
- Write the intention before the action. A row saying "about to do this", keyed on something stable, before the call goes out.
- Record a claim timestamp and sweep stale claims, so a crash mid-request leaves a recoverable record and not a permanently stuck one.
- Run one retry layer, not two. Node-level retries inside a workflow that also gets retried as a whole is how attempts get miscounted.
- Know what your retry skips. Retrying from the failed node does not re-run your guard. If the guard matters, it has to live where a resumed run still meets it, or in the external system.
- Alert on the runs that finish green with nothing in them. Zero of eight is not success, and nothing in the platform will tell you otherwise.
When this is a job to hand over
Adding an idempotency key to one API call is an afternoon, and if you can see which call needs it, do it yourself.
It becomes a job when money has already gone out twice and somebody has to work out who was charged what, when nobody can say whether a half-finished run left records in three systems, or when the workflow has grown two layers of retries and a checkpoint that fires in the wrong place. Work like that has a shape and a ceiling, which is how Fix S and Fix M are priced, and the n8n work we take is scoped this way.
Related, if you are here because something already ran twice: the causes of an automation firing twice are not all retries, and the fix differs by cause. If the records being written twice live in a spreadsheet, that has its own set of traps.
Sources
- Partial failures when an n8n workflow calls multiple APIs - n8n Community, 30 August to 3 September 2026, read 6 September 2026. The partial-failure problem stated by the person hitting it, and the checkpoint-before-the-call pattern with a stable operation key.
- Duplicate Processing When an n8n Workflow Is Retried - n8n Community, 3-4 September 2026, read 6 September 2026. A timeout after the work completed, the race between two retries, the stuck-row failure mode, and the advice to turn off node-level retries on the API node.
- How to make an n8n lead-intake workflow safe to retry without creating duplicates - n8n Community, 17-18 August 2026, read 6 September 2026. A retry from the failed node skipping the claim entirely, and the error-output setting that lets execution walk past a duplicate guard.
- Handle Failed n8n Workflows Without Losing Data - n8n Community, 10-11 August 2026, read 6 September 2026. The run that does not fail and loses data quietly, and the error workflow that cannot fire if n8n is not alive.
- Handle API rate limits and retries in n8n without creating duplicate requests - n8n Community, 20 August 2026, read 6 September 2026. Node-level retries finishing before the database update, so an attempt counter never increments, and the advice to run one retry layer rather than two.
- View executions for a single workflow - n8n Docs, read 6 September 2026. The two retry options as documented, with no mention of resuming, of which node the run continues from, or of executions that cannot be retried.
- Work with nodes - n8n Docs, read 6 September 2026. Retry On Fail described as rerunning until it succeeds, and the On Error options.
- Remove Duplicates - n8n Docs, read 6 September 2026. Removing items processed in previous executions, the Value Is New setting, scope, and the default history size of ten thousand items.
- Types of executions - n8n Docs, read 6 September 2026. Partial executions running preceding nodes, and production executions ignoring all pinned data.
- n8n-io/n8n - n8n source, read 6 September 2026. The failed node pushed back onto the execution stack, the retry clearing the last node's error and letting the stack continue, the clamped retry parameters, and the errors raised for aborted, queued and successful executions.
- Idempotent requests - Stripe API documentation, read 6 September 2026. Saved results regardless of success or failure, the twenty-four hour pruning window, the parameter comparison, and which request methods accept keys.
Broken workflow? Fix S — $300, 2 business days, fixed price.
Get my quote in 24hWritten by the Fixmation team.