DEV Community

FlowPatch Reliability
FlowPatch Reliability

Posted on

When an n8n API timeout may already have committed

An n8n HTTP Request node can fail even when the remote system has already accepted the request.

That is the most dangerous kind of failure: not a clean rejection, but an ambiguous commit.

Suppose a workflow does this:

  1. Receive a lead webhook.
  2. POST the lead to a CRM.
  3. Wait 30 seconds.
  4. The request times out.
  5. Retry the workflow.

The retry may be correct if the CRM never received the first request. It may create a duplicate if the CRM committed the lead at second 29 but the response never reached n8n.

A green retry is not proof that the workflow is correct. It can mean the same business action happened twice.

The rule that prevents most duplicates

For every side-effecting request, generate one stable operation identity before the first attempt and reuse it for every retry.

operation_key = "create-lead:" + source_event_id
Enter fullscreen mode Exit fullscreen mode

Do not generate the key inside the retrying node. Do not use the execution attempt ID if it changes across retries. The key must identify the intended business action, not the transport attempt.

If the provider supports idempotency keys, send that value in the provider's documented header. If it does not, store the key and provider result in a durable table you control.

A useful state model is:

prepared -> attempted -> confirmed
                    \-> ambiguous -> reconciled
                    \-> terminal_failure
Enter fullscreen mode Exit fullscreen mode

ambiguous is a real state. Treating a timeout as a simple failed state erases the most important fact: the provider may have committed.

What the n8n workflow should persist

Before calling the provider, persist:

  • stable operation key;
  • source event ID;
  • request fingerprint;
  • provider name and endpoint;
  • state = prepared.

After sending, record the attempt. On a definite success, store the provider object ID and mark confirmed. On a definite rejection, record the safe-to-retry or terminal result.

On a timeout, broken connection, or malformed response, mark ambiguous. Do not immediately create a new business operation.

The next step should reconcile:

  1. Look up the operation by provider idempotency key, external reference, or request fingerprint.
  2. If the provider object exists, store its ID and mark confirmed.
  3. If it definitely does not exist, retry with the same operation key.
  4. If the provider cannot answer conclusively, route to bounded delayed retry or operator review.

Webhook callbacks do not remove the need for state

A common design is "POST the job, then wait for the callback." That still has two failure windows:

  • The provider accepts the job, but the initial response is lost.
  • The provider sends the callback, but your workflow crashes after the side effect and before durable acknowledgement.

Webhook handlers should durably accept first, deduplicate on the provider event ID, and make downstream side effects replay-safe. Returning 200 before durable acceptance can lose an event. Returning an error after the side effect can invite a duplicate delivery.

Five failure-path tests worth running

The happy path is only one test. Add these:

  1. Timeout after provider commit

    Simulate a committed object with a lost response. Verify the next run reconciles instead of creating a second object.

  2. Duplicate source webhook

    Deliver the same source event twice. Verify one business operation and one stored provider ID.

  3. Crash after side effect

    Stop execution after the provider accepts but before the workflow records success. Verify replay uses the same operation key.

  4. Callback before listener registration

    Deliver the provider callback immediately. Verify it is durably stored even if the waiting execution has not registered its in-memory listener yet.

  5. Permanent 4xx

    Return an authentication or validation error. Verify it does not enter the same retry loop as a transient 429 or 503.

A quick boundary review

For one n8n-to-provider boundary, write down four facts:

  • provider/API;
  • trigger;
  • observed failure;
  • current retry behavior.

Those four facts are usually enough to define the first failure map: where identity is created, what can commit, which outcomes are ambiguous, and how reconciliation should work.

I offer a fixed $99 n8n/API failure-path diagnostic for one boundary. It includes a boundary-specific risk matrix, retry and state rules, patch plan, failure-path tests, and an implementation estimate. Delivery is within two business days after written scope and cleared ACH; the fee is credited toward a $299 implementation patch purchased within 14 days.

The service is independent and is not affiliated with n8n.

Top comments (0)