Claude API Error Codes
Every Claude API error explained: 401 invalid x-api-key, 429 rate_limit_error, 529 Overloaded, 413 request_too_large, and the 400s newer models introduced. Exact response text, cause and fix for each.
Every error is returned as JSON with the same envelope, so you can branch on error.type without parsing the message text:
{"type":"error","error":{"type":"authentication_error","message":"invalid x-api-key"}}Match on the HTTP status and error.type, never on the message string — messages are prose and can be reworded, while the type is a contract. In the official SDKs this means catching the typed exception classes rather than inspecting text. This page is written the other way round only because the message is what you have in front of you when something breaks.
All codes
| Status | error.type | Meaning | Retry? |
|---|---|---|---|
| 401 | authentication_error | invalid x-api-key | No |
| 429 | rate_limit_error | rate limit exceeded | Yes, back off |
| 529 | overloaded_error | Overloaded | Yes, back off |
| 400 | invalid_request_error | credit balance is too low | No |
| — | subscription usage cap (not an API error) | Claude usage limit reached — subscription cap, not an API error | Yes, back off |
| 400 | invalid_request_error | prompt is too long | No |
| 400 | invalid_request_error | tool_use without a matching tool_result | No |
| 400 | invalid_request_error | temperature and top_p cannot both be specified | No |
| 400 | invalid_request_error | max_tokens must exceed thinking.budget_tokens | No |
| 400 | invalid_request_error | assistant message prefill not supported | No |
| 400 | invalid_request_error | max_tokens above the model's output ceiling | No |
| 413 | request_too_large | request too large | No |
| 404 | not_found_error | model or endpoint not found | No |
| 403 | permission_error | permission denied | No |
| 400 | invalid_request_error | Streaming required for long operations | No |
| 402 | invalid_request_error | insufficient balance or key spending limit reached | No |
| 400 | invalid_request_error | invalid anthropic-beta header | No |
| 400 | invalid_request_error | could not parse request body | No |
| 500 | api_error | internal server error | Yes, back off |
401 — invalid x-api-key
HTTP 401
{"type":"error","error":{"type":"authentication_error","message":"invalid x-api-key"}}Why it happens
- The x-api-key header is missing or empty — often because the environment variable is unset in the shell that actually runs the process.
- The key is sent in the wrong header. ANTHROPIC_API_KEY becomes x-api-key; ANTHROPIC_AUTH_TOKEN becomes Authorization: Bearer. A valid key in the wrong header still returns this error.
- Both ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN are set, so both headers go out and the request is rejected. An empty string still counts as set.
- The key was revoked, or expired if it was issued with an expiry date.
- The key is fine but the base URL points somewhere that has never seen it.
How to fix it
- Print the first few characters of the variable inside the same process that fails. Most 401s are an environment or quoting problem rather than a bad key.
- Pick one variable and unset the other. This is the single most common cause when a custom base URL is involved.
- Confirm the key is active in your dashboard, and that the base URL matches the key's issuer.
Check what is actually being sent
# Is the variable set in THIS shell?
echo "${ANTHROPIC_API_KEY:0:12}…"
# Is a competing variable also set?
env | grep -E 'ANTHROPIC_(API_KEY|AUTH_TOKEN|BASE_URL)'
curl https://api.apitoken.sale/v1/models \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01"Other forms of the same failure
401 - {'type': 'error', 'error': {'type': 'authentication_error', 'message': 'invalid x-api-key'}}litellm.AuthenticationError: AnthropicException - invalid x-api-keyanthropic.AuthenticationErrorclaude code 401 custom ANTHROPIC_BASE_URLcursor bad user api key unauthorized anthropic
Short link: https://apitoken.sale/e/invalid-api-key · Identical on api.anthropic.com and on this gateway.
429 — rate limit exceeded
HTTP 429
{"type":"error","error":{"type":"rate_limit_error","message":"This request would exceed your organization's rate limit of 80,000 input tokens per minute. Please reduce the prompt length or the maximum tokens requested, or try again later."}}Why it happens
- The per-minute token or request ceiling was exceeded. The number in the message is your own limit, so it differs between accounts.
- A burst with no concurrency ceiling — a parallel map over a large list is the usual culprit.
- Retries piling on top of the requests that caused the first 429, which enlarges the burst instead of draining it.
- A single very large prompt can exceed a per-minute token budget on its own, which is why the message suggests shortening the prompt as well as waiting.
How to fix it
- Honour the Retry-After header rather than guessing an interval.
- The official SDKs already retry 429 and 5xx with exponential backoff (twice by default) — raise max_retries instead of hand-rolling a loop.
- Cap concurrency at the call site. A semaphore fixes more 429s than any retry policy.
- Do not confuse this with a subscription usage cap — see the usage-limit entry below. They are different systems with different fixes.
Let the SDK back off for you
import anthropic
client = anthropic.Anthropic(max_retries=5) # retries 429 and 5xx with backoffOther forms of the same failure
Number of request tokens has exceeded your per-minute rate limitanthropic.RateLimitErrorclaude api 429 too many requests
Short link: https://apitoken.sale/e/rate-limit · Identical on api.anthropic.com and on this gateway.
529 — Overloaded
HTTP 529
{"type":"error","error":{"type":"overloaded_error","message":"Overloaded"}}Why it happens
- Upstream capacity is temporarily saturated. 529 describes the service, not your request.
- It clusters during incidents: the same request typically succeeds minutes later with no change.
How to fix it
- Retry with exponential backoff and jitter. Never in a tight loop — that is what produced the pile-up.
- Note the status is 529, not 503. Some HTTP clients and proxies only treat a hardcoded set of codes as retryable and omit 529, so the retry you think you have may not fire.
- For latency-sensitive paths, fall back to a smaller model, which is generally less contended.
Other forms of the same failure
API Error: 529 {"type":"error","error":{"type":"overloaded_error","message":"Overloaded"}}anthropic api overloaded error repeated 529claude 529 vs 429
Short link: https://apitoken.sale/e/overloaded · Identical on api.anthropic.com and on this gateway.
400 — credit balance is too low
HTTP 400
{"type":"error","error":{"type":"invalid_request_error","message":"Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits."}}Why it happens
- The Anthropic organization behind the key has no API credits left. API credits are a separate wallet from a Pro or Max subscription.
- A Pro or Max subscriber sees this because the tool is authenticating with an API key rather than the subscription — the subscription does not fund API calls.
- Auto-reload is off, or the card on file was declined.
How to fix it
- Check whether the failing tool is using an API key or a subscription login. This error always concerns API credits.
- Add credits to the organization, or enable auto-reload so long jobs do not stop mid-run.
- On this gateway the equivalent condition is a 402 with a different message — see the insufficient-balance entry.
Other forms of the same failure
claude credit balance is too low but I have creditsclaude pro credit balance too lowyour credit balance is too low to access the anthropic api
Short link: https://apitoken.sale/e/credit-balance-too-low · Identical on api.anthropic.com and on this gateway.
Claude usage limit reached — subscription cap, not an API error
Claude usage limit reached. Your limit will reset at 3pm (America/New_York)Why it happens
- This is a Claude Pro or Max subscription cap, not an HTTP error from the API. It comes from the apps and from Claude Code when signed in with a subscription.
- Caps are enforced on a rolling window (commonly a five-hour session window plus a weekly ceiling), so heavy days can exhaust a weekly allowance well before the week ends.
- It is unrelated to a 429: the API's rate limits are per-minute throughput, while this is a plan allowance.
How to fix it
- Wait for the stated reset time — the message names it, and it is a rolling window rather than a calendar boundary.
- Reduce what each request carries. Long conversations resend their whole history every turn, so trimming or compacting context stretches an allowance considerably.
- If the work cannot wait for a reset, pay-as-you-go API access is billed per token instead of per plan allowance, so it has no weekly cap to exhaust. That is the honest difference: metering, not a way around an enforcement action.
Other forms of the same failure
Claude AI usage limit reachedclaude weekly limit reachedclaude max 20x weekly limitwhen does claude usage limit resetлимит claude исчерпан когда сбросится
Short link: https://apitoken.sale/e/usage-limit-reached · Comes from Anthropic's own apps and subscription plans, not from this gateway.
400 — prompt is too long
HTTP 400
{"type":"error","error":{"type":"invalid_request_error","message":"prompt is too long: 212164 tokens > 199999 maximum"}}Why it happens
- The request exceeds the model's context window. The two numbers are your prompt size and the ceiling for that model.
- An agent loop that appends every tool result to the history without ever pruning it.
- Large files or documents pasted inline rather than referenced.
How to fix it
- Count before sending: the count_tokens endpoint gives an exact, model-specific number. Do not estimate with a tokenizer built for another vendor — it undercounts Claude noticeably.
- Prune old tool results from the history, or enable server-side compaction so earlier turns are summarized instead of resent verbatim.
- Upload large documents once via the Files API and reference them by file_id.
Other forms of the same failure
claude prompt is too long tokens > maximumclaude 200k context limit error
Short link: https://apitoken.sale/e/prompt-too-long · Identical on api.anthropic.com and on this gateway.
400 — tool_use without a matching tool_result
HTTP 400
{"type":"error","error":{"type":"invalid_request_error","message":"`tool_use` ids were found without `tool_result` blocks immediately after: toolu_… Each `tool_use` block must have a corresponding `tool_result` block in the next message."}}Why it happens
- The assistant turn requested one or more tools, and the next message did not return a result for every one of them.
- Only the text was appended to the history instead of the full response content, so the tool_use blocks were silently dropped.
- Several tools were requested in parallel and the results were split across multiple user messages instead of batched into one.
- A tool threw, and the code skipped sending a result rather than sending an error result.
How to fix it
- Append the entire response content to the history, not just the text.
- Return every tool_result for a turn inside a single user message. Splitting them also trains the model to stop making parallel tool calls.
- On failure, still return a tool_result with is_error set — never omit it.
Other forms of the same failure
tool_use ids were found without tool_result blocksclaude code tool_result error
Short link: https://apitoken.sale/e/tool-result-missing · Identical on api.anthropic.com and on this gateway.
400 — temperature and top_p cannot both be specified
HTTP 400
{"type":"error","error":{"type":"invalid_request_error","message":"`temperature` and `top_p` cannot both be specified for this model. Please use only one."}}Why it happens
- Both sampling parameters were sent to a Claude 4 model. Frameworks commonly set defaults for both, so the code may never have set them explicitly.
- On Claude Opus 4.7 and later — including Opus 4.8, Opus 5 and Fable 5 — the parameters were removed entirely, so sending either one returns a 400.
- On Claude Sonnet 5 a non-default value is rejected while the default is accepted, so the same code can pass on one route and fail on another.
How to fix it
- On Claude 4.x, send at most one of the two.
- On Opus 4.7 and later, delete both, plus top_k. There is no replacement parameter — behaviour is steered by prompting and by the effort setting.
- If temperature=0 was there for determinism, note it never guaranteed identical output on any model.
Before and after
# Before — 400
client.messages.create(model="claude-opus-5", temperature=0.7, top_p=0.9, …)
# After
client.messages.create(model="claude-opus-5", …)Other forms of the same failure
temperature and top_p cannot both be specifiedclaude opus temperature removedbedrock claude temperature and topP error
Short link: https://apitoken.sale/e/temperature-and-top-p · Identical on api.anthropic.com and on this gateway.
400 — max_tokens must exceed thinking.budget_tokens
HTTP 400
{"type":"error","error":{"type":"invalid_request_error","message":"`max_tokens` must be greater than `thinking.budget_tokens`"}}Why it happens
- On models that still accept a fixed thinking budget, that budget must be strictly smaller than max_tokens, since thinking and the reply share the same output allowance.
- On Claude Opus 4.7 and later and on Sonnet 5 the fixed budget was removed altogether, which surfaces as a different 400 telling you to use adaptive thinking and the effort setting instead.
How to fix it
- Raise max_tokens above the budget, or lower the budget.
- On current models, switch to adaptive thinking and control depth with output_config.effort (low, medium, high, xhigh, max). Effort goes inside output_config, not at the top level.
- With thinking enabled, max_tokens caps thinking plus reply together — a budget sized for the answer alone can truncate mid-response.
Current form
thinking={"type": "adaptive"},
output_config={"effort": "high"}Other forms of the same failure
max_tokens must be greater than thinking.budget_tokens"thinking.type.enabled" is not supported for this model"thinking.type.disabled" is not supported for this modelbudget_tokens removed claude
Short link: https://apitoken.sale/e/thinking-budget-tokens · Identical on api.anthropic.com and on this gateway.
400 — assistant message prefill not supported
HTTP 400
{"type":"error","error":{"type":"invalid_request_error","message":"This model does not support assistant message prefill. The conversation must end with a user message."}}Why it happens
- The conversation ends on an assistant message used to force the opening of the reply. That is rejected on Claude Opus 4.6 and later, Sonnet 4.6 and later, and Fable 5.
- Assistant messages elsewhere in the history — few-shot examples, for instance — are still fine. Only a trailing one is rejected.
- Many frameworks prefill internally, so the code may never do it explicitly.
How to fix it
- To force a JSON shape, use structured outputs via output_config.format instead of prefilling an opening brace.
- To force a label, define a tool with an enum field listing the valid labels.
- To suppress a preamble, instruct it in the system prompt: respond directly, with no opening phrases.
- To continue an interrupted response, move the continuation into the user turn and quote where it stopped.
Other forms of the same failure
This model does not support assistant message prefillclaude prefill trailing whitespace error
Short link: https://apitoken.sale/e/prefill-not-supported · Identical on api.anthropic.com and on this gateway.
400 — max_tokens above the model's output ceiling
HTTP 400
{"type":"error","error":{"type":"invalid_request_error","message":"max_tokens: 128001 > 128000, which is the maximum allowed number of output tokens for claude-opus-4-6"}}Why it happens
- max_tokens exceeds the output ceiling for that specific model. The ceiling is per model and is not the same as the context window.
- A configuration written for one model reused with another that has a lower ceiling.
How to fix it
- Look up the ceiling for the model you are calling rather than assuming a shared value.
- Above roughly 16K output tokens, stream the response — a large non-streaming request can exceed the SDK's HTTP timeout even when max_tokens is legal.
Other forms of the same failure
which is the maximum allowed number of output tokensclaude max_tokens too large
Short link: https://apitoken.sale/e/max-tokens-too-large · Identical on api.anthropic.com and on this gateway.
413 — request too large
HTTP 413
{"type":"error","error":{"type":"request_too_large","message":"Request exceeds the maximum size"}}Why it happens
- The serialized body exceeds the size ceiling. Base64-encoded images and PDFs are the usual reason.
- Base64 inflates binary data by roughly a third, so a file that looks safe on disk can be over the limit on the wire.
- Requests can hit an intermediate ceiling below the documented maximum when many files are attached at once.
How to fix it
- Resize or recompress images before encoding — most vision tasks do not need the original resolution.
- Upload large documents once via the Files API and reference them by file_id rather than resending bytes each turn.
- Trim the message history instead of replaying every turn verbatim.
Other forms of the same failure
claude api 413 request_too_largeclaude request exceeds the maximum size
Short link: https://apitoken.sale/e/request-too-large · Identical on api.anthropic.com and on this gateway.
404 — model or endpoint not found
HTTP 404
{"type":"error","error":{"type":"not_found_error","message":"model: claude-opus-4-5-20251101"}}Why it happens
- A model id that does not exist: a typo, a date suffix appended to an alias, or an id retired in a deprecation wave.
- Model ids use hyphens throughout — claude-sonnet-4-6, never claude-sonnet-4.6.
- A base URL that already ends in /v1, so the SDK produced /v1/v1/messages.
How to fix it
- Set the base URL to the origin only and let the SDK append /v1 itself.
- List the models the key can actually reach instead of guessing an id.
- Replace retired ids: Claude 3.7 Sonnet and Claude 3.5 Sonnet map to claude-sonnet-5, Claude 3.5 Haiku to claude-haiku-4-5, Claude 3 Opus to claude-opus-5.
List the models this key can use
curl https://api.apitoken.sale/v1/models \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01"Other forms of the same failure
claude api 404 not_found_error modelcursor model not found anthropic api keyclaude-3-5-sonnet 404
Short link: https://apitoken.sale/e/not-found · Identical on api.anthropic.com and on this gateway.
403 — permission denied
HTTP 403
{"type":"error","error":{"type":"permission_error","message":"Your API key does not have permission to use the specified resource."}}Why it happens
- The key is valid but not entitled to the model or feature requested.
- A regional restriction. This variant often arrives with a terser body such as 'Request not allowed' and is about where the request originates, not about the key.
- On the Anthropic API a billing problem can also surface as 403, distinguished by the error type rather than the status.
How to fix it
- Branch on error.type, not on the status alone — it separates a permission problem from a billing one.
- Try a model you know the key can reach, to establish whether the key itself is healthy.
- For a regional block, the fix is where the request egresses from, not the key. This gateway accepts requests from regions where the upstream API is not directly reachable.
Other forms of the same failure
anthropic 403 Request not allowedclaude api 403 forbidden country
Short link: https://apitoken.sale/e/permission-denied · Identical on api.anthropic.com and on this gateway.
Streaming required for long operations
HTTP 400
{"type":"error","error":{"type":"invalid_request_error","message":"Streaming is strongly recommended for operations that may take longer than 10 minutes"}}Why it happens
- A non-streaming request was made with a max_tokens large enough that the response could exceed the request timeout.
- It shows up most in no-code and workflow tools, where the node sets a large max_tokens but does not expose a streaming toggle.
How to fix it
- Stream the request and collect the final message from the stream helper.
- If streaming is not available in your tool, lower max_tokens to something the timeout can accommodate — roughly 16K output tokens is a safe non-streaming ceiling.
Stream and take the final message
with client.messages.stream(model="claude-opus-5", max_tokens=64000, …) as stream:
message = stream.get_final_message()Other forms of the same failure
Streaming is required for operations that may take longer than 10 minutes
Short link: https://apitoken.sale/e/streaming-required · Identical on api.anthropic.com and on this gateway.
402 — insufficient balance or key spending limit reached
HTTP 402
{"type":"error","error":{"type":"invalid_request_error","message":"insufficient balance or key spending limit reached for this request"}}Why it happens
- The prepaid balance does not cover the request just submitted.
- The key carries its own spending limit and has reached it, even though the account still has balance.
- A large max_tokens reserves a correspondingly large hold up front, so a request can be refused while the balance still looks non-zero. The unused part of the hold is released when the request settles.
How to fix it
- Top up the balance, or raise the spending limit on that key.
- Lower max_tokens to what the response actually needs — the hold is sized from max_tokens, not from the tokens finally used.
- Read the live balance with the same key you use for inference.
Check the balance for a key
curl https://api.apitoken.sale/balance \
-H "x-api-key: $ANTHROPIC_API_KEY"Other forms of the same failure
claude api 402api key spending limit reached
Short link: https://apitoken.sale/e/insufficient-balance · This response is specific to this gateway — the Anthropic API has no equivalent.
400 — invalid anthropic-beta header
HTTP 400
{"type":"error","error":{"type":"invalid_request_error","message":"invalid anthropic-beta header"}}Why it happens
- The anthropic-beta header carries a flag this gateway does not accept, or the value is malformed.
- Several flags joined by something other than a comma.
- A flag copied from documentation for a feature that has since gone GA and no longer takes a header.
How to fix it
- Send multiple flags as one comma-separated value.
- Drop flags for features that are now GA — effort, fine-grained tool streaming and the 128K output header among them.
- If the SDK sets the header for you, do not also set it by hand.
Other forms of the same failure
anthropic-beta header error
Short link: https://apitoken.sale/e/invalid-beta-header · This response is specific to this gateway — the Anthropic API has no equivalent.
400 — could not parse request body
HTTP 400
{"type":"error","error":{"type":"invalid_request_error","message":"Could not parse request body."}}Why it happens
- The body is not valid JSON — a trailing comma, a single-quoted string, or a shell variable that expanded into an unescaped quote.
- A missing or non-JSON Content-Type header.
How to fix it
- Validate the body before sending. Most of these never reach the API in a working state.
- In shell scripts, build the body with a heredoc or jq rather than string interpolation.
Other forms of the same failure
claude api could not parse request body
Short link: https://apitoken.sale/e/invalid-request-body · This response is specific to this gateway — the Anthropic API has no equivalent.
500 — internal server error
HTTP 500
{"type":"error","error":{"type":"api_error","message":"Internal server error"}}Why it happens
- An unexpected failure while processing the request. Nothing in your payload caused it.
How to fix it
- Retry with exponential backoff — the SDKs do this for 5xx automatically.
- If it persists for one request while others succeed, capture the request id and send it to support.
Other forms of the same failure
anthropic api_error internal server error
Short link: https://apitoken.sale/e/api-error · Identical on api.anthropic.com and on this gateway.
Still stuck?
If a request fails in a way this page does not cover, send us the endpoint, the masked key id, the HTTP status and the response body. Never send the full key.
apiToken.sale serves the standard Anthropic Messages API, so every non-gateway error on this page behaves exactly as it does against api.anthropic.com. See also the rate limits guide and how to point an SDK at a custom base URL.