Solving Claude API Errors: 400, 401, 403, 404, 413, 429, 500, 529 — The Complete Guide
Full catalog of Anthropic API errors: every code (400, 401, 403, 404, 413, 429, 500, 529), its cause, how to diagnose it, and how to fix it. With concrete curl examples, LiteAI/Bifrost response samples, and a three-step runbook covering 90% of cases.
Solving Claude API Errors: 400, 401, 403, 404, 413, 429, 500, 529 — The Complete Guide
The query "api error claude" consistently ranks on Yandex at around 1,000 impressions per month — it's the second most frequent technical query in the Claude niche, after "claude code." And unlike most "how to buy"-type queries, this one is a pure pain point: the developer is already working with the API, something broke, and they're hunting for the fix. Right now, in the moment.
This article is a complete catalog of Anthropic API errors: every code (400, 401, 403, 404, 413, 429, 500, 529, 529), its cause, how to diagnose it, and how to fix it. With concrete curl examples, LiteAI/Bifrost response samples, and a unified cheat-sheet table.
If you're still falling over after reading this — there's a working three-step runbook covering 90% of cases at the end of the article.
What a Claude API error is and where it occurs
When your code sends a request to the Anthropic API (POST https://api.anthropic.com/v1/messages), the server can respond in two ways:
- At the HTTP level. A 4xx/5xx code plus a JSON body with
error.typeanderror.messagefields. These are structured errors described in the Anthropic spec. - At the network level. Timeouts, ECONNRESET, DNS errors, TLS resets. These are stack errors (Node.js
fetch,curl, Pythonrequests) with no HTTP code at all.
The LiteAI proxy (https://api.liteai.tech/anthropic) and the official Anthropic API return the same structured errors — because LiteAI simply proxies your request to Bifrost/Anthropic with your sk-bf-… key. So a single guide covers both integrations.
The full error map
| Code | Meaning | When it occurs | Fixed on the client side? | Severity |
|---|---|---|---|---|
| 400 | Bad Request | Malformed request body | Yes, fix the code | 🟡 |
| 401 | Unauthorized | Missing/invalid API key | Yes, check the key | 🔴 |
| 403 | Permission Denied | Key lacks access rights to the model/endpoint | Yes | 🟡 |
| 404 | Not Found | Nonexistent endpoint or wrong region | Yes | 🟡 |
| 413 | Payload Too Large | Request exceeds the limit (images/PDFs) | Partially | 🟡 |
| 429 | Too Many Requests | Rate limit/quota exceeded | Partially (retry) | 🟡 |
| 500 | Internal Server Error | Anthropic/Bifrost server-side error | Retry | 🟠 |
| 529 | Overloaded | All models busy, try later | Retry (with backoff) | 🟠 |
| 503/504 | Unavailable/Gateway | Network error or regional degradation | Retry | 🟡 |
| 521/522/523/524 | Cloudflare | Cloudflare can't reach the upstream | Retry | 🟡 |
Except for 401/403, all errors are usually transient and are solved by retrying with growing intervals. 401 and 403 are code bugs or account issues — retrying won't help.
400 — Bad Request
Response body:
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "messages: roles must alternate between \"user\" and \"assistant\""
}
}
Typical causes (from LiteAI experience):
- Roles must alternate — two consecutive messages with the same role in the
messagesarray. For example[{role:"user"}, {role:"user"}]. Fix: interleave them with assistant messages or merge the content. - Messages must be non-empty — an empty array. At least one user message.
- Temperature: invalid value — greater than 1.0 or less than 0. The Claude API accepts 0.0–1.0.
- max_tokens: too large — more than 8192 for Opus 4.8 / Sonnet 4.6. This is a per-request limit, not monthly.
- System: too long — more than 100K tokens in the system prompt. Trim it or move it to Prompt Caching.
- Unknown model —
claude-4-opusis specified instead ofclaude-opus-4-8. Model list: Anthropic docs → Models.
Diagnosis:
curl https://api.liteai.tech/anthropic/v1/messages \
-H "x-api-key: $LITEAI_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{...}' -i | head -20
When the error is there — look at the error.type field (usually invalid_request_error) and error.message. They almost always point to a specific field in your JSON.
How to prevent it: use the Anthropic SDK instead of raw JSON. The SDK validates types at compile time.
401 — Unauthorized
Response body:
{
"type": "error",
"error": {
"type": "authentication_error",
"message": "invalid x-api-key"
}
}
Causes:
x-api-keyheader not passed. Check that it's set on every request, not just the first one.- The key expired or was revoked. On LiteAI, the
sk-bf-…key lives while the balance hasn't been spent. If the balance = 0, the key is formally valid but requests return 402 Payment Required (see below — LiteAI-specific), not 401. - Prod/dev key mix-up. If you have two environments and two key pairs, it's easy to swap them.
- ANTHROPIC_AUTH_TOKEN vs x-api-key. The Anthropic SDK has two auth methods: the
x-api-keyheader andAuthorization: Bearer. If you're using the SDK — check that you're settingapi_key, notauth_token.
Quick key test:
curl https://api.liteai.tech/anthropic/v1/models \
-H "x-api-key: $LITEAI_KEY" \
-H "anthropic-version: 2023-06-01" | jq
If the response is an array of models, the key is valid. If it's authentication_error — hunt for the cause.
403 — Permission Denied
Response body:
{
"type": "error",
"error": {
"type": "permission_error",
"message": "Your API key does not have access to claude-opus-4-8"
}
}
Causes:
- The model is unavailable for your key. For example, Opus 4.8 isn't enabled on every plan. On LiteAI, Opus 4.8 / Sonnet 4.6 / Haiku 4.5 / fable-5 are available to everyone.
- Regional block. If you're using
region: "EU"and the model has no EU instance (rare with Anthropic). - Org-level permissions. In the Anthropic Console via
claude.aiyou can create custom org permissions.
Diagnosis:
import anthropic
client = anthropic.Anthropic(api_key="sk-bf-...")
try:
client.messages.create(model="claude-opus-4-8", max_tokens=10, messages=[{"role":"user","content":"ping"}])
except anthropic.PermissionDeniedError as e:
print(e)
In the SDK, the error becomes a typed exception with a clear message.
404 — Not Found
Response body (Anthropic-specific):
{"type":"error","error":{"type":"not_found_error","message":"/v1/messagez: model not found"}}
Or for LiteAI: an empty 404 with an nginx HTML body.
Causes:
- Typo in the path.
/v1/messagesvs/v1/messagez. The SDK catches this; raw curl — no. - Wrong
ANTHROPIC_BASE_URL. For LiteAI it'shttps://api.liteai.tech/anthropic. For direct Anthropic —https://api.anthropic.com. - Regional routing. AWS/GCP regions have different hostnames; a 404 often means "you're in the wrong region."
- The model doesn't exist at this endpoint. For example,
claude-2is already deprecated.
Diagnosis: check ANTHROPIC_BASE_URL with echo, make sure the URL has no trailing slash, and verify the model exists via the /v1/models endpoint.
413 — Payload Too Large
Response body:
{"type":"error","error":{"type":"request_too_large","message":"Request exceeds the maximum size (max: 32 MB for non-vision)"}}
Causes:
- Image/PDF exceeds the limit. The per-image limit is 5 MB, the per-PDF limit is 32 MB. Above that — 413.
- Long context. A single request with a 200K-token context plus a base64 image can exceed 32 MB. Solution — send the image via the Files API or compress it.
- Many tool definitions. Each tool is roughly 500 tokens. 100 tools × 500 = 50K tokens of JSON. Anthropic accepts roughly 50 tools per request, but the payload grows.
Solutions:
- Compress images before sending (Node's
sharp, Python'sPillow). - Use the Files API for large PDFs — the Anthropic API supports
file_idreferences instead of inline base64. - Split long contexts via prompt caching and summarization.
429 — Too Many Requests
Response body:
{
"type": "error",
"error": {
"type": "rate_limit_error",
"message": "Number of request tokens per minute (RPM) exceeded: 50"
}
}
This is the most common production error. Anthropic has multi-tier rate limits:
| Tier | RPM | TPM | Availability conditions |
|---|---|---|---|
| Free | 5 | 25K | First day |
| Build Tier 1 | 50 | 100K | After $5 spend |
| Build Tier 2 | 1000 | 1M | After $50 spend |
| Build Tier 3+ | 4000+ | 4M+ | After $500+ spend |
On LiteAI, rate limits are softer (we don't impose a hard per-minute cutoff — we serve what we have and queue things during peaks), so a 429 on LiteAI usually means "the proxy node is overloaded," not "you blew past your limit."
Solutions:
- Exponential backoff —
1s, 2s, 4s, 8s, 16s, 32swith jitter. - Batch requests — if the API supports
batches(Anthropic doesn't yet; OpenAI and Google do), submit an offline batch. - Prompt Caching — cuts TPM 10× (from 100K to 10K for a repeated system prompt).
- Parallelism via workers — several processes with different keys.
- Streaming — lowers TTFB and slot occupancy time.
Python retry-logic example (works stably in production):
import time, random
import anthropic
def with_retry(fn, max_attempts=5):
for attempt in range(max_attempts):
try:
return fn()
except anthropic.RateLimitError:
if attempt == max_attempts - 1: raise
delay = (2 ** attempt) + random.uniform(0, 1)
time.sleep(delay)
500 — Internal Server Error
Response body:
{"type":"error","error":{"type":"api_error","message":"Internal server error"}}
What it means: a server-side error on the Anthropic or LiteAI side. Your code isn't at fault.
Fix:
- Retry with exponential backoff — Anthropic usually recovers in 1–30 seconds.
- Check the status page: status.anthropic.com or our channel.
- If 5xx persists for more than 5 minutes — it's a production incident. Temporarily switching to OpenAI API or DeepSeek via OpenRouter is acceptable.
On LiteAI-Bifrost production, 500 errors in the last 90 days happened 3 times, all lasting under 90 seconds.
529 — Overloaded
Response body:
{"type":"error","error":{"type":"overloaded_error","message":"Anthropic API is temporarily overloaded, please retry"}}
How it differs from 500: 529 is "all the chips are busy." It's a normal state during peak hours (11:00–14:00 ET, 14:00–17:00 UTC). Models really are overloaded in the moment.
Fix: same as 500 — retry with backoff. But the strategy differs:
- For 5xx — retry faster (1, 2, 4, 8 seconds).
- For 529 — retry slower (10, 20, 40 seconds). The chips may only free up after a minute.
Falling back to another model also helps:
models_in_order = ["claude-opus-4-8", "claude-sonnet-4-6", "claude-haiku-4-5"]
for model in models_in_order:
try:
return client.messages.create(model=model, ...)
except anthropic.APIStatusError as e:
if e.status_code in (500, 529) and model != models_in_order[-1]:
continue # fallback
raise
Haiku 4.5 is roughly 10× cheaper than Opus 4.8 and never gets overloaded (its inference runs on a separate pool). When Opus is overloaded, falling back to Haiku doesn't save the logic, but it does save you on errors.
503/504 — Unavailable / Gateway Timeout
503: the server is temporarily unavailable, usually the proxy layer (Cloudflare, AWS ALB).
504: the wait for the upstream server timed out (nginx proxy_read_timeout).
On LiteAI, a 504 is our nginx waiting on Bifrost. It's a rare event in the logs and usually correlates with large payloads or network spikes. Retry logic works the same way as for 500.
Runbook: what to do when something breaks (3 steps in 90 seconds)
If you're reading this in "everything is broken right now" mode — here's a fast algorithm:
Step 1. Pin down the code (5 seconds).
curl https://api.liteai.tech/anthropic/v1/messages \
-H "x-api-key: $LITEAI_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model":"claude-haiku-4-5","max_tokens":10,"messages":[{"role":"user","content":"ping"}]}' \
-s -w "\n%{http_code}\n"
If the response is 200 OK — your main code is breaking something concrete (a model, a payload); the problem is there. If it's 401/403 — it's the key. If it's 500/529 — retry.
Step 2. Check the key (10 seconds).
curl https://api.liteai.tech/anthropic/v1/models \
-H "x-api-key: $LITEAI_KEY" \
-H "anthropic-version: 2023-06-01" | jq 'if type == "array" then "✅ OK" else .error.message end'
If it's ✅ OK — the key is valid. If it's an error — read the error message.
Step 3. Check the provider's status (30 seconds).
- status.anthropic.com — Anthropic's official status
- The LiteAI Telegram channel (we post there when there are problems) — that's where you can see whether our Bifrost is down
If LiteAI is fine and Anthropic is degraded — wait 5–10 minutes. If everything is fine everywhere — it's a bug in your code; read the error.message field more carefully.
Production best practices
1. Always use the SDK. The Anthropic SDK catches 95% of errors as typed exceptions — RateLimitError, AuthenticationError, NotFoundError. Faster than parsing JSON.
2. Exponential backoff with jitter. On each retry, grow the pause ×2 and add random ±20% jitter. This reduces the "thundering herd" of 100 workers all retrying at the same instant.
3. Watch the retry_after_header. Some 429s carry Retry-After: 30 — honor it instead of your own backoff strategy.
4. Log the request-id. Every Anthropic response has a request-id: req_… header. If the error is reproducible — that ID is critically important when you reach out to support.
5. Split the retry logic by error type:
- 401, 403 — don't retry; alert.
- 400 — don't retry; fix the code.
- 404 — don't retry; check the URL.
- 413 — don't retry; trim the payload.
- 429 — retry with backoff.
- 500, 502, 503, 504, 529 — retry with backoff.
- Timeouts — retry.
6. LiteAI-specific: payment. If you have a LiteAI key and it returns 402 Payment Required, it means balance = 0. Top up on /pricing — the balance doesn't expire; the minimum package is 30 ₽ / 1M tokens.
When to contact support
If you've completed all three runbook steps, the problem doesn't reproduce on Haiku 4.5, and both the Anthropic and LiteAI statuses are clean — gather:
- The
request-idfrom the response. - A UTC timestamp (second precision).
- Full curl with a redacted key (replace
sk-bf-...withsk-bf-REDACTED). - Your scenario: what you were trying to do and what you expected to happen.
Then write to Telegram @liteaitech_bot or support@liteai.tech. LiteAI support response time — usually within an hour during business hours.
What's next
If you're hitting the same error systematically:
- Persistent 429s → your case is bigger than your tier. Move up to Tier 2+, use prompt caching, or cut the parallelism.
- Persistent 529s → you're working during peak hours (16:00 UTC). Schedule batch jobs overnight (00:00–08:00 UTC), when traffic is 4× lower.
<string>: OpenAI API error 400from Claude Code → often means the Anthropic SDK inside Claude Code is using the OpenAI format via the LiteAI route. Make sureANTHROPIC_BASE_URLpoints at/anthropic/v1, not at/v1(the OpenAI format). See the article on setting up Claude Code.
To unlock production-grade capabilities — check out the Claude Code pillar and the Claude Code subscription in RF — they explain how to dodge 90% of the pain around limits and payments that leads to these errors in the first place.
Ready to try LiteAI?
An Anthropic API key for Claude Opus, Sonnet and Haiku — in 30 seconds, paid with USDT.