Claude API errors fall into roughly three groups: credentials and request format, rate limits and capacity, and context length. Work through them in that order. Check the HTTP status code and error type first, then the request ID, and only then consider changing the prompt. Do it the other way around and you will easily mistake a configuration problem for a model problem.
This article breaks down four common failures—401, 429, 529 overloaded, and context length—and gives the causes, troubleshooting steps, and reusable backoff code for each. Model and pricing details follow the model pricing page.
Note: Anthropic and Claude are trademarks of their respective owners. Error types and API behavior can change between versions. This article describes common cases as of October 2026 and defers to the official documentation.
1. Read the status code before you edit the prompt
| Status | Error type | Typical meaning | Retry? |
|---|---|---|---|
| 400 | invalid_request_error | Bad parameters, format, or context length | Fix the request, then retry |
| 401 | authentication_error | Key missing, wrong, or expired | Do not retry; fix credentials first |
| 403 | permission_error | Key lacks model or project permission | Do not retry; check permissions |
| 404 | not_found_error | Wrong path or model name | Do not retry; check the documentation |
| 413 | request_too_large | Request body too large | Split the request, then retry |
| 429 | rate_limit_error | Rate, concurrency, or token limit exceeded | Back off and retry |
| 500 | api_error | Internal server error | Back off and retry |
| 529 | overloaded_error | Server overloaded | Back off and retry |
Keep the request-id response header. When you ask a provider to investigate, one request ID is worth more than ten screenshots. At minimum, log the timestamp, status code, error type, model name, and request ID. Never log full keys or sensitive content.
2. 401: check the headers, then the key
A 401 means authentication failed. It has nothing to do with your balance or the model's capabilities. Check these items in order:
- Are you sending
x-api-keyrather thanAuthorization: Bearer? The Claude Messages API does not use a Bearer token. - Are you including
anthropic-version: 2023-06-01? A missing version header sometimes surfaces as a 400, but adding it is the simpler fix. - Does the key have leading or trailing spaces, line breaks, or stray quotes? Copying from a chat window is the most common cause.
- Did the environment variable actually load? Log the prefix only—never print the full key.
- Has the key been revoked, and does it belong to the current organization or project?
- Does the base URL point to the correct environment, and is the path
/v1/messages?
export ANTHROPIC_API_KEY="sk-your-key"
curl "https://ai.zhongshangqihang.com/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-5-5",
"max_tokens": 64,
"messages": [{"role": "user", "content": "Reply with OK only"}]
}'
If this command returns 200, the key, base URL, and model name are all correct. If you still get a 401, try the same key against another endpoint to separate a key problem from a gateway configuration or network problem. Model names follow model pricing.
3. 429: rate limiting is not "insufficient balance"
A 429 means the request exceeded a rate or quota limit. Common triggers:
- Requests per minute or tokens per minute exceeded.
- A sudden spike in concurrency that exhausts the quota in a short window.
- Several services sharing one key and competing for the same quota.
- Retries without backoff, so every failure produces more requests and a retry storm.
- Long outputs consuming more output tokens and leaving less room for concurrency.
| Symptom | Likely cause | Action |
|---|---|---|
| 429s cluster at peak hours | Traffic spike | Queue requests and smooth the send rate |
| 429s with one key across services | Shared quota | Split keys by project |
| Worse after adding retries | Retries without backoff | Exponential backoff with jitter |
| Long requests hit 429 first | High output-token usage | Lower max_tokens or concurrency |
Check the retry-after header if present before deciding how long to wait. SDKs distinguish RateLimitError from a generic APIStatusError; branch on the type, not on string matching the error message.
import random
import time
from anthropic import Anthropic, APIStatusError, RateLimitError
client = Anthropic()
def ask(prompt: str, retries: int = 4) -> str:
for attempt in range(retries):
try:
resp = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=1024,
messages=[{"role": "user", "content": prompt}],
)
return resp.content[0].text
except RateLimitError:
wait = min(2 ** attempt, 20) + random.random()
print(f"429, retry {attempt + 1}, waiting {wait:.1f}s")
time.sleep(wait)
except APIStatusError as exc:
if exc.status_code >= 500:
wait = min(2 ** attempt, 20) + random.random()
print(f"{exc.status_code}, retrying in {wait:.1f}s")
time.sleep(wait)
continue
raise
raise RuntimeError("Retries exhausted")
Retries only help with transient errors. For operations that already produced side effects, use an idempotency key or a state check to confirm whether the operation ran before resending.
4. 529 overloaded: server overload, not your quota
A 529 with overloaded_error means the service is under heavy load. It is usually unrelated to your own usage. It differs from a 429: with a 429 you inspect your concurrency and quota; with a 529 you check service status and reduce pressure.
- Confirm the error type is
overloaded_error. Do not treat it as an invalid key. - Preserve the
request-idand the time it occurred so the provider can investigate. - Use exponential backoff with random jitter, set a maximum retry count, and avoid aggressive fixed-interval retries.
- Reduce concurrency, queue requests to smooth peaks, and temporarily disable non-critical jobs if necessary.
- Prepare a fallback model or backup channel, but make sure the business can tolerate a change in output quality.
- If the problem lasts longer than expected, contact the provider and include the request ID.
Retrying every second turns a small incident into an avalanche. A retry policy needs a ceiling and an alert; it must never loop forever.
5. Context limits: measure first, then split
A context-limit error usually returns 400 invalid_request_error with prompt is too long in the message. The model is not broken; the combined input and output budget exceeds the context window.
Common sources include uncropped message history, tool results that return an entire log, whole documents pasted in, too many images, and an oversized system prompt. Work in this order:
- Measure the input with
count_tokensbefore sending. Do not guess from character counts. - Trim the oldest history, keeping the system prompt, the most recent turns, and a summary.
- Retrieve relevant passages from documents first. Do not load an entire corpus.
- Split long documents by chapter, process the sections, and merge the results afterward.
- Compress tool output to the necessary fields instead of carrying the full response back on every turn.
- Leave room for output.
max_tokenscaps the output, but input and output must both fit inside the context window.
import os
from anthropic import Anthropic
client = Anthropic()
MODEL = "claude-sonnet-5-5"
LIMIT = int(os.environ.get("CONTEXT_BUDGET", "200000")) # Team budget, not the model ceiling
def fit_messages(messages):
while client.messages.count_tokens(model=MODEL, messages=messages).input_tokens > LIMIT:
if len(messages) <= 2:
raise ValueError("A single message exceeds the budget; split the document")
messages = messages[2:] # Drop the oldest user/assistant turn
return messages
Here LIMIT is a budget your team sets, not a model specification. Setting it below the model ceiling leaves headroom for output and tool calls.
6. A troubleshooting order
- Record the status code, error type,
request-id, model name, and timestamp. - For 401 and 403, check credentials and permissions. For 404, check the path and model name.
- For 400, check parameters, context length, image format, and request body size.
- For 429, check quota, concurrency, shared keys, and retry storms.
- For 529, check service status, back off, reduce concurrency, and prepare a fallback.
- For 500, back off and retry first. If it persists, contact the provider with the request ID.
- After every incident, add monitoring and alerts. Do not wait for user reports to find out.
FAQ
What is the difference between 429 and 529?
A 429 means your requests exceeded a rate or quota limit, so check your own concurrency, keys, and usage first. A 529 means the server is overloaded, so back off, reduce concurrency, and check service status. Both require retries, but they point in different directions.
Why do requests still fail after I added retries?
You may be missing backoff, running too much concurrency, sharing one key across services, or sending a request that is simply a 400. Retries solve transient errors; they cannot fix bad parameters or permission problems.
Does prompt is too long mean the model is broken?
No. It means the input exceeds the context window. Measure it with count_tokens, then trim history, split documents, or add retrieval. Do not keep adding prompt text.
How many times should I retry?
There is no universal number. Set a ceiling based on what the workload can tolerate—three to five attempts, for example—then degrade or alert. Backoff intervals should increase and include random jitter so clients do not resend simultaneously.
How do I tell a gateway error from an upstream error?
Look at the error type and request-id, then send the same request to both the official endpoint and the gateway. That quickly separates key, network, gateway configuration, and upstream service problems.
Next steps
Create a test key at the ZSQH AI Gateway, rehearse each of 401, 429, 529, and context-limit once, then connect production monitoring. Model availability and pricing follow model pricing.
Related reading:
