Failure pattern · 1 documented incident
Duplicate action after an ambiguous result
A request times out, the caller assumes it failed and retries, and the money moves (or the order ships) twice.
See it happen
Watch how this failure unfolds, then switch to the same situation with the safeguard in place. Click any step to replay it.
Scroll the diagram sideways to see every system.
Ana is refunded twice, and every further retry would pay again.
What goes wrong:
- The agent asks the payments API to refund Ana $50.
- The money moves, but the reply is lost on the way back.
- Assuming the refund failed, the agent sends it again.
- Ana is refunded twice, and every further retry would pay again.
With the safeguard:
- Each refund carries a unique idempotency key.
- The reply is lost again.
- The retry reuses the same key, so the API recognises it and returns the first result.
- One refund, no matter how many retries.
What it is
A request that changes something (a payment, an order, a message) times out. The caller can’t tell whether it worked, assumes it didn’t, and sends it again. The first one had gone through, so now it happens twice.
How it happens
- Your system calls a payments, messaging or provisioning API that it doesn’t control
- The network drops or a gateway returns 502/504 after the other side has already done the work
- Retry logic resends the request with nothing that marks it as the same request
What it causes
- Customers charged, refunded or paid twice
- Orders shipped twice, tickets or seats allocated twice
- Your ledger and the provider’s records drift apart
Warning signs
- Two transactions for what the customer meant as one action
- Bursts of client timeouts immediately followed by success responses
- Order status in your database disagrees with the payment provider
How to prevent it
Make every consequential call idempotent. Send a client-generated idempotency key with each state-changing request, treat timeouts as "unknown" rather than "failed", and check the remote status before retrying.
- Every request that moves money or changes state carries a unique idempotency key
- A timeout is treated as “unknown”, not as “failed”
- Before retrying a consequential action, the system checks what actually happened
Key ideas:Idempotency key
Check your system against the full launch checklistReal incidents with this pattern
Documented incidents first. Each links to its public source.
Design reference: idempotency keys make retried payment API calls safe (Stripe)
Stripe explains that a client which cannot tell whether a request succeeded (for example after a network failure) needs to retry safely, and that without protection a retried charge could double-charge a customer.
Safeguard: Attach idempotency keys to state-changing requests
16 security advisories and illustrative scenarios with this pattern
Software component issue could cause actions to run with inconsistent state
A public security advisory describes this issue. Review the linked source for the technical details and remediation guidance.
Software component issue could cause actions to run with inconsistent state
A public security advisory describes this issue. Review the linked source for the technical details and remediation guidance.
Software component issue could cause actions to run with inconsistent state
A public security advisory describes this issue. Review the linked source for the technical details and remediation guidance.
Software component issue could cause actions to run with inconsistent state
A public security advisory describes this issue. Review the linked source for the technical details and remediation guidance.
Software component issue could cause actions to run with inconsistent state
A public security advisory describes this issue. Review the linked source for the technical details and remediation guidance.
Software component issue could cause actions to run with inconsistent state
A public security advisory describes this issue. Review the linked source for the technical details and remediation guidance.
Software component issue could cause actions to run with inconsistent state
A public security advisory describes this issue. Review the linked source for the technical details and remediation guidance.
Software component issue could cause actions to run with inconsistent state
A race condition vulnerability exists in the request processing logic of the REST management interface on Brocade Fabric OS versions before 10.0.1.
Autonomous AI Agent Model Context Protocol Token Hijacking
Model Context Protocol search tool allowed prompt injection to leak bearer tokens in subagent prompt context.
JWT Secret Key Confusion & Privilege Escalation
Backend accepted HMAC-SHA256 tokens signed with public RSA key, allowing attacker to forge administrator tokens.
Distributed Rate Limiter Redis Key Collision & Global Lockout
Missing tenant namespace prefix in rate limiter Redis key caused single user limit to apply globally to all tenants.
OAuth Refresh Token Reuse Race Condition & Account Takeover
Simultaneous token refresh requests from multi-tab sessions triggered false reuse detection, locking user accounts.
In the standards
CollectSEA's mapping; not an official determination by the standards bodies.