A Claude API 429 is not automatically a reason to keep retrying, and a 529 is not a reason to add an unlimited outer loop. First identify the failure, then give one layer ownership of the attempt count and the end-to-end deadline. If output or tool effects may already exist, decide what can safely be replayed before sending another request.
This guide targets developers operating the first-party Claude Messages API. It reviews the current official documentation on November 1, 2026; it does not reproduce an outage or test an SDK integration. Bedrock, Foundry, proxies, and agent frameworks can introduce different error mappings and additional retry layers. Inspect their actual configuration rather than transferring these assumptions unchanged.
Is this a rate limit, a spend cap, or overload?
The official error reference identifies 429 as a rate-limit error that can also represent a tier spend cap or a Claude Code workspace spend limit. 529 means temporary API overload. A sharp increase in traffic can also trigger acceleration limits. The status code starts the diagnosis; it does not finish it. Claude API errors
For a Messages API tier spend-cap failure, the documented discriminator is error.details.error_code with the value enforced_spend_limit_reached. These responses lack retry-after; retries fail until access resumes. Do not reverse that implication: the absence of the header alone is not proof of a spend cap. The rate-limit documentation explicitly says that not every 429 includes it. Spend caps and response headers
Use this triage order:
- Explicit spend-cap signal: stop the immediate retry path and report an account-limit condition. Do not silently raise a spending limit.
- Rate-limit response with a wait instruction: account for that wait in the remaining deadline; reduce demand rather than immediately resending.
- 529 overload: consider a bounded retry, not an authentication change or a larger token allowance.
- Unclassified 429: preserve the error type, documented detail fields, request ID, and available headers. Investigate before assigning a cause.
For throughput diagnosis, distinguish requests per minute, input tokens per minute, and output tokens per minute. A short burst can exceed enforcement even when a minute-wide average looks acceptable. Rate-limit definitions
Why did one user action send nine attempts?
The Python SDK documents two retries by default for selected connection/status failures, including 429 and server errors. That means up to three attempts, counting the initial request. max_retries controls this behavior. Timeouts are also retried by default. Python SDK retry configuration
Fictional arithmetic example, not a traffic measurement: an application calls the SDK up to three times, and every SDK call exhausts its initial attempt plus two retries. The resulting ceiling is:
3 application calls
× 3 attempts per SDK call
= up to 9 attempts
That ceiling assumes every failure is retryable, no earlier success, no cancellation, and no additional proxy retries. It is not a prediction of billable generations or a universal SDK trace.
AWS’s reliability guidance describes retry multiplication across layers, recommends choosing a retry point for suitable operations, and explains why backoff plus jitter helps avoid synchronized bursts. It also warns that a timeout does not prove a side effect failed to happen. AWS retry guidance
Our design recommendation: write down the owner before changing retry counts. Either let the SDK handle the bounded transport retries, or deliberately disable them and let a tested application policy own them. Inventory gateway, queue, and workflow retries too. Disabling SDK retries without replacing required recovery is not a reliability improvement by itself.
The map is a decision aid, not an implementation or proof of exactly-once execution.
Does the next retry still fit the user’s deadline?
A network timeout setting is not a substitute for a product-level deadline that includes queueing, earlier attempts, and waits. The Python documentation exposes configurable timeout behavior and warns that timeout failures can themselves be retried. Check the semantics of your installed SDK and HTTP transport. Python SDK timeouts
Fictional planning example: a user interaction has a 20-second deadline. The first attempt consumes 6 seconds. The server asks for an 8-second wait. Only 6 seconds remain afterward, before accounting for other overhead.
If your application requires a further 7-second allowance to attempt useful work, another attempt does not fit. End the interactive operation or offer a separately bounded background workflow if the product supports one. Do not shorten the server’s wait merely to squeeze the request into the UI deadline.
The 7-second allowance is an invented policy choice, not an observed Claude latency percentile. Choose a real allowance from your workload’s latency and failure data. Enforce cancellation and attempt limits in the implementation; a subtraction written in a design document cannot stop a request.
HTTP 200 arrived. Why did the answer still fail?
A streaming response can carry an error after HTTP 200. The documented event flow ends with message_stop; an overload may instead appear as an SSE error event. Treat stream completion separately from the initial HTTP status. Streaming event flow and errors
Our recovery rule is to keep transport attempts, displayed output, and committed actions separate:
- Mark an interrupted answer as incomplete; do not silently label it a successful result.
- If starting a fresh generation, decide explicitly whether to replace or retain partial text. Blindly appending a new answer can duplicate or contradict it.
- Before replaying an agent workflow, reconcile any tool action already performed. A fresh model request is not evidence that a prior external write did not happen.
This is not a claim that the model API automatically repeats your client-side tools. The risk comes from how your application resumes or restarts the workflow. For the separate problem of completed responses with insufficient output budget, use the response truncation diagnostic. For durable side-effect recovery, see idempotency crash windows.
What should you record before increasing retries?
Use an application operation ID to group attempts, and record the provider request ID when available. The provider documents request IDs for debugging. Request ID reference
For your own telemetry, record the retry owner, attempt number, elapsed time, remaining deadline, error classification, chosen wait, and whether output or an action was committed. Avoid logging API keys or full prompts merely to investigate a retry.
Before raising a limit, answer three questions:
- Did the extra attempt recover a transient failure, or just extend an already failed interaction?
- Did attempts per completed operation grow faster than successful operations?
- Can the workflow safely reconcile an uncertain outcome without repeating an external action?
Those observations support a retry policy. A larger retry count alone does not establish higher reliability, lower cost, or a better user experience.
Sources & scope
Official API and SDK documentation with an original retry decision map and fictional arithmetic examples. No live API requests, outage reproduction, SDK integration tests, or latency benchmarks.
- Claude API errors
- Claude rate limits and spend caps
- Anthropic Python SDK: retries and timeouts
- Claude streaming messages
- AWS Builders Library: timeouts, retries, and backoff with jitter
Publishing details & corrections
Prepared with AI assistance. Sources, any tests performed, and their limitations are described in the article.
No material corrections recorded for this version.