July 8, 2026claude api error

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:

  1. At the HTTP level. A 4xx/5xx code plus a JSON body with error.type and error.message fields. These are structured errors described in the Anthropic spec.
  2. At the network level. Timeouts, ECONNRESET, DNS errors, TLS resets. These are stack errors (Node.js fetch, curl, Python requests) 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):

  1. Roles must alternate — two consecutive messages with the same role in the messages array. For example [{role:"user"}, {role:"user"}]. Fix: interleave them with assistant messages or merge the content.
  2. Messages must be non-empty — an empty array. At least one user message.
  3. Temperature: invalid value — greater than 1.0 or less than 0. The Claude API accepts 0.0–1.0.
  4. max_tokens: too large — more than 8192 for Opus 4.8 / Sonnet 4.6. This is a per-request limit, not monthly.
  5. System: too long — more than 100K tokens in the system prompt. Trim it or move it to Prompt Caching.
  6. Unknown modelclaude-4-opus is specified instead of claude-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:

  1. x-api-key header not passed. Check that it's set on every request, not just the first one.
  2. 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.
  3. Prod/dev key mix-up. If you have two environments and two key pairs, it's easy to swap them.
  4. ANTHROPIC_AUTH_TOKEN vs x-api-key. The Anthropic SDK has two auth methods: the x-api-key header and Authorization: Bearer. If you're using the SDK — check that you're setting api_key, not auth_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:

  1. 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.
  2. Regional block. If you're using region: "EU" and the model has no EU instance (rare with Anthropic).
  3. Org-level permissions. In the Anthropic Console via claude.ai you 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:

  1. Typo in the path. /v1/messages vs /v1/messagez. The SDK catches this; raw curl — no.
  2. Wrong ANTHROPIC_BASE_URL. For LiteAI it's https://api.liteai.tech/anthropic. For direct Anthropic — https://api.anthropic.com.
  3. Regional routing. AWS/GCP regions have different hostnames; a 404 often means "you're in the wrong region."
  4. The model doesn't exist at this endpoint. For example, claude-2 is 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:

  1. Image/PDF exceeds the limit. The per-image limit is 5 MB, the per-PDF limit is 32 MB. Above that — 413.
  2. 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.
  3. 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's Pillow).
  • Use the Files API for large PDFs — the Anthropic API supports file_id references 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:

  1. Exponential backoff1s, 2s, 4s, 8s, 16s, 32s with jitter.
  2. Batch requests — if the API supports batches (Anthropic doesn't yet; OpenAI and Google do), submit an offline batch.
  3. Prompt Caching — cuts TPM 10× (from 100K to 10K for a repeated system prompt).
  4. Parallelism via workers — several processes with different keys.
  5. 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:

  1. Retry with exponential backoff — Anthropic usually recovers in 1–30 seconds.
  2. Check the status page: status.anthropic.com or our channel.
  3. 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:

  1. The request-id from the response.
  2. A UTC timestamp (second precision).
  3. Full curl with a redacted key (replace sk-bf-... with sk-bf-REDACTED).
  4. 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 400 from Claude Code → often means the Anthropic SDK inside Claude Code is using the OpenAI format via the LiteAI route. Make sure ANTHROPIC_BASE_URL points 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.