All articles

Architecture essay

When Retry-After Meets a Pruned Idempotency Key

A practical analysis of uncertain HTTP outcomes: label recovery guidance as recommendation, honor Retry-After, retain the original idempotency key, and check provider-specific retention before any late retry.

Why outcome remains uncertain

An HTTP operation can reach recovery with incomplete knowledge. A timeout means no usable response arrived. It does not establish whether the provider completed the request.

Recommendation: classify this state as an uncertain outcome. Do not treat it as proof of completion or as permission to start a fresh operation.

A fresh operation can create duplicate side effects if the first request completed. Assuming completion can leave the requested action unresolved. This is a recovery design risk, not a claim about a measured incident.

Recovery has two separate decisions. First, decide when to send a follow-up request. Second, decide which operation identity that request carries.

Retry-After addresses timing. An idempotency key addresses duplicate-control behavior while the provider still recognizes that key. Neither control answers both questions.

MDN documents Retry-After as guidance on how long the user agent should wait before making a follow-up request. MDN lists 503 Service Unavailable and 429 Too Many Requests as uses.

Recommendation: honor that timing guidance when a response includes Retry-After. The header does not establish whether an earlier uncertain request completed.

Stripe documents a separate API v1 rule. Idempotency keys may be removed after they are at least 24 hours old. Reusing a key after pruning generates a new request.

Recommendation: treat provider retention as part of recovery analysis. The 24-hour behavior belongs to Stripe API v1. It is not a universal HTTP rule.

When Retry-After Meets a Pruned Idempotency Key: Uncertain HTTP Outcome; Retry-After Guidance; Idempotency-Key Retention
When Retry-After Meets a Pruned Idempotency Key: Uncertain HTTP Outcome; Retry-After Guidance; Idempotency-Key Retention

Three named concepts

Uncertain HTTP Outcome means recovery begins without reliable confirmation that the original request completed. A timeout is one hypothetical trigger.

Recommendation: retain the original operation identity while deciding how to recover. This keeps uncertainty visible instead of silently converting recovery into a new operation.

Retry-After Guidance means server-provided timing advice for a follow-up request. Its documented meaning is wait-time guidance, including use with 429 and 503 responses.

Recommendation: use Retry-After Guidance to set the earliest follow-up time. Do not treat it as proof that replay remains duplicate-safe.

Idempotency-Key Retention means the period during which a provider still recognizes an idempotency key under its documented policy.

Stripe API v1 may prune keys after at least 24 hours. After pruning, reuse generates a new request. Clients may not be able to directly verify whether a key remains retained.

Recommendation: check documented provider policy and any available provider state before a late retry. If retention cannot be verified, mark that uncertainty explicitly.

Stripe also documents parameter comparison. Incoming parameters are compared with the original request parameters. Different parameters produce an error.

Recommendation: when reusing a retained key, preserve the original parameters. Do not combine an old key with a changed operation and call it a replay.

Adjacent connections

Uncertain HTTP Outcome identifies why recovery needs care, while Retry-After Guidance states how long to wait before making a follow-up request.

Retry-After Guidance sets timing for recovery from Uncertain HTTP Outcome, but it does not establish whether the original request completed.

Retry-After Guidance determines when a follow-up request may be sent, while Idempotency-Key Retention determines whether the original key may still provide provider-defined duplicate-control behavior.

Idempotency-Key Retention limits the safety assumptions attached to Retry-After Guidance when the wait extends beyond provider-specific policy.

These connections separate evidence from synthesis. MDN supports the timing meaning of Retry-After. Stripe supports its documented key and parameter behavior.

The ordering below is engineering guidance derived from those separate facts. It is not presented as a new protocol result or an observed outcome.

Recovery decision

State or inputDecisionBoundary
No usable responseLabel Uncertain HTTP OutcomeCompletion remains unknown
Retry-After presentWait as directedTiming does not prove completion
Key likely retainedReuse original key and parametersProvider policy still governs behavior
Retention expired or unknownReconcile or expose duplicate riskClient may not verify retention directly

First, label the result as an Uncertain HTTP Outcome when the client cannot establish what happened. Keep the original idempotency key.

This is a recommendation for preserving operation identity. It does not promise that the provider will recognize the key forever. That question belongs to Idempotency-Key Retention.

Second, apply Retry-After Guidance before sending a follow-up request. If the response includes Retry-After, wait for the indicated period.

This is a recommendation to respect server timing. Waiting does not prove that the original request failed, completed, or remains protected by the same key.

Third, check the provider's retention policy before a late retry. For Stripe API v1, keys may be removed after they are at least 24 hours old.

The client may not have a direct way to verify pruning. A documented window can inform the decision, but it cannot establish current provider state in every deployment.

If the original key may have been pruned, reuse can generate a new request under Stripe's documented API v1 behavior. Mark that outcome as duplicate risk, not as equivalent to a protected replay.

Fourth, preserve original parameters when reusing a retained key. Stripe documents an error when incoming parameters differ from those of the original request.

Finally, use reconciliation before another request when retention is uncertain or likely expired. Reconciliation can determine whether the original operation completed, if the provider exposes a suitable way to check.

If reconciliation is unavailable, require an explicit decision. Stopping avoids a new request. Proceeding accepts duplicate risk. The system should expose that boundary to operators or callers.

Hypothetical cases and limits

Hypothetical case: a request times out, and the client cannot determine whether the provider completed it. The client records an Uncertain HTTP Outcome and retains the original key.

The provider response includes Retry-After. The client follows Retry-After Guidance, then considers whether documented Idempotency-Key Retention still covers the key.

If the key remains retained, the client can attempt the same parameters under the original key, subject to provider behavior. If the key was pruned, Stripe documents that reuse generates a new request.

A second hypothetical case changes one parameter during recovery. Stripe's documented comparison can return an error. The changed request must not be described as the same replay.

These cases are design examples. They are not observed incidents, personal experience, or measured outcomes. They show why timing, operation identity, and provider retention need separate state.

The client also may not know whether a provider has pruned a key at the exact moment of retry. That uncertainty limits what client-side logic can claim.

A retry flag alone cannot represent all relevant states. At minimum, recovery needs outcome uncertainty, wait guidance, key identity, parameter consistency, and retention confidence.

That state model remains provider-specific at its edges. Stripe's API v1 rule supplies one documented retention policy. Other providers can define different windows or semantics.

Sources and design boundary

Retry-After and idempotency keys solve different parts of recovery. Retry-After addresses when the client should wait. An idempotency key addresses repeated-operation identity while recognized.

A plan that checks only Retry-After can wait correctly and still issue a new request after key pruning. A plan that checks only retention can preserve a key while ignoring server timing.

Recommendation: honor the wait guidance, then assess whether the original key still has the provider-defined behavior the retry depends on. If that assessment is unavailable, expose the uncertainty.

The durable principle is narrow: retain operation identity through uncertain outcomes, follow Retry-After guidance, preserve original parameters, and verify provider policy before a late retry.

This principle does not guarantee success or eliminate duplicate risk. It defines a clearer decision boundary for recovery when client knowledge is incomplete.

https://docs.stripe.com/api/idempotent_requests

https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Retry-After

Related field notes