Skip to content
Mastering Claude

Home / When things go wrong

When things go wrong9 minApplication

API errors and rate limits

A call to the API can fail in several different ways: a 400 or 404 error most often signals a malformed request that must be corrected before any retry, except for the special case of a 400 returned for a spending cap that has been reached, whereas a 429 error only resolves itself by waiting if it carries a Retry-After header, which is not the case for a spending cap that has been reached.

An error returned by the Anthropic API carries a status code that distinguishes very different causes. A 400 error, invalid_request_error, or a 404, not_found_error, signals a malformed request: an invalid parameter, incorrect content, or a model identifier that no longer exists as written. Retrying that call without correcting it reproduces the same error indefinitely, the only way out is to bring the call back in line with the specification currently in force. A model identifier that has changed name since a script was written explains a good part of these 400 and 404 errors: the current documentation for the model in use remains the first thing to open before suspecting anything else. A 400 is not always a malformed request, however: the API also returns this code when usage reaches a spending cap set for the organisation or the workspace, except on the Claude Code workspace, which can then return a 429 instead. In that particular case, correcting the request achieves nothing, it is the cap itself that must be raised.

Not every 429 error resolves itself by waiting

A 429 error, rate_limit_error, signals a cap being reached, but two distinct caps produce this same code. A temporary rate that has been exceeded carries a Retry-After header and resolves itself by respecting the delay it indicates before retrying. A spending cap reached for a tier, on the other hand, carries no Retry-After header at all: the documentation says so plainly, such a 429 keeps failing without let-up until access is restored. Waiting in the face of such a response achieves nothing: continuing to retry in this case wastes calls for nothing and delays the real solution, which is raising the cap set by the organisation before resuming the sending of requests.

HTTP/1.1 429 Too Many Requests
retry-after: 12

{"type":"error","error":{"type":"rate_limit_error"}}

The presence or absence of this header, not the 429 code alone, decides between waiting and acting otherwise.

In Claude Code, two variables govern the retries

A 529 error, overloaded_error, displays a message in Claude Code stating that the API is at full capacity, without touching the session's usage quota. This detail matters: a series of 529 errors can be worrying without actually eating into the volume of usage the subscription allows. Claude Code automatically retries 429 and 529 errors of the temporary rate type, never a 429 caused by a gateway's spending cap. CLAUDE_CODE_MAX_RETRIES bounds the number of attempts, CLAUDE_CODE_RETRY_WATCHDOG allows retrying indefinitely in an unsupervised session: the figure accompanying this lesson gives the exact values.

Deciding whether to wait or act otherwise already comes up in a stuck command, where the same choice arises when facing a silence that could signal a genuine stall or work still in progress.

Figure 1

Four status codes, their cause, and the right recovery move

Status codeMeaningLikely causeRecovery move
400invalid_request_errorInvalid parameter or malformed content, sometimes a spending cap set by the organisationCorrect the request before any retry, check the cap on the organisation side
404not_found_errorIncorrect endpoint or model identifierCheck the exact identifier in the current documentation before retrying
429rate_limit_errorTemporary rate exceeded, or a tier spending cap reachedWait for the delay in the Retry-After header if it is present, otherwise do not wait
529overloaded_errorAPI capacity saturated, specific to Claude CodeLet Claude Code retry automatically, without this touching the usage quota
The table cross references four status codes cited in the body with their technical meaning, their likely cause, and the recovery move that matches each one.
Figure 2

Automatic retries and the Batch API rate

10default retries
default number of retries on a temporary 429 or 529 error, variable CLAUDE_CODE_MAX_RETRIES
code.claude.com/docs/en/errors, 2026-09-02
15retries, cap
cap on the number of retries that CLAUDE_CODE_MAX_RETRIES can reach
code.claude.com/docs/en/errors, 2026-09-02
50% of standard rate
rate reduction applied to asynchronous processing by the Batch API, compared with the standard API
platform.claude.com/docs/en/build-with-claude/batch-processing, 2026-09-02
These three values bound the number of retries Claude Code performs on a temporary error, and the rate reduction applied to asynchronous batch processing.
Calibrate it yourself

A script sends a call to the Anthropic API that fails with a 429 code. The response contains a retry-after header set to twelve seconds. The developer schedules a retry after exactly that delay.

Write, in one sentence, what this situation establishes, and in one sentence what it does not establish.

What to remember
  • An outdated model identifier or a malformed parameter causes a 400 or 404 error, which should not be retried as is without correcting the request first, except for the special case of a 400 returned for a spending cap that has been reached, where it is the cap that must be raised.
  • A 429 error covers two distinct caps: a temporary rate, which resolves by respecting the delay given in the Retry-After header, and a tier spending cap, which carries no such header and does not resolve by waiting.
  • A 529 error in Claude Code signals that the API's capacity is saturated and does not touch the session's usage quota.
  • Claude Code automatically retries 429 and 529 errors of the temporary rate type, never a 429 tied to a gateway's spending cap.
  • The Batch API processes requests asynchronously, at a reduced rate compared with the standard API, for a use case that can tolerate a processing delay rather than an immediate response.
Do this now

Send a call to the API with an invalid, made up model name, for example claude-inexistant, read the status code returned and the type field in the JSON error response, then confirm that this is indeed a malformed request rather than a rate limit.

Check the source

Every datable claim in this lesson links here to the public text behind it. A source that does not open proves nothing.