Why Is the Claude API Not Working? Common Fixes
If your Claude API calls are failing, the cause is almost always one of six things: an invalid or expired API key, a rate limit you've hit, a temporary overload on Anthropic's side, a malformed request body, a network/timeout issue, or your account running out of credits. The fix depends entirely on which one it is, and the fastest way to find out is to read the actual error code instead of guessing.
This article walks through each failure mode, what the error response looks like, and what to do about it. Most "Claude API not working" problems take under five minutes to diagnose once you know where to look.
Start With the HTTP Status Code
Every failed request returns a status code and a JSON body with an error.type field. That combination tells you almost everything:
- 401 Unauthorized — your API key is missing, invalid, or revoked
- 403 Forbidden — your key doesn't have access to the requested model or resource
- 429 Too Many Requests — you've hit a rate limit (requests per minute or tokens per minute)
- 400 Bad Request — the request body is malformed (wrong field, bad JSON, invalid parameter)
- 500 Internal Server Error — something went wrong on the API's side
- 529 Overloaded — the API is at capacity and temporarily rejecting new requests
If you're only seeing "Claude API not working" with no further detail, add logging that prints the full response body, not just a generic "request failed" message. The error.message field almost always names the exact problem.
Invalid or Expired API Key (401)
This is the single most common cause. Things that trigger it:
- The key was copied with a trailing space or missing characters
- The key was rotated or revoked in the console and old code still uses the previous value
- The
Authorizationheader is missing theBearerprefix or uses the wrong header name entirely - Environment variables aren't loaded correctly (a classic
.envfile that wasn't sourced, or a deployment that didn't pick up the new secret)
Test the key in isolation before touching your application code:
curl https://api.anthropic.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-4-20250514",
"max_tokens": 100,
"messages": [{"role": "user", "content": "hello"}]
}'
If this fails with a 401, the key itself is the problem — regenerate it and update every place it's stored (local .env, CI secrets, deployed environment variables).
Rate Limits (429)
Anthropic enforces both requests-per-minute and tokens-per-minute limits, and they vary by usage tier. If you're sending bursts of concurrent requests — common in batch jobs, agent loops, or load tests — you'll hit 429s even though your total daily volume is low.
Fixes:
- Add exponential backoff with jitter on 429 responses
- Check the
retry-afterheader if present and respect it - Reduce concurrency in batch scripts (process in smaller chunks with delays)
- If this happens consistently under normal traffic, your usage tier may need to increase, which usually requires sustained spend history
Overloaded Errors (529)
A 529 means the API is temporarily rejecting requests due to high demand, not something wrong in your code. These spike during peak hours or right after new model releases. The correct response is the same as for rate limits: retry with backoff. Don't treat a 529 as a permanent failure — most resolve within seconds to a couple of minutes.
Malformed Request Body (400)
Common culprits:
- Missing
max_tokens, which is a required field - Mixing
systemprompt content into themessagesarray instead of using the dedicatedsystemparameter - Sending an empty
messagesarray - Using a model name that's been deprecated or doesn't exist
- Invalid tool schema when using tool use — check that
input_schemais valid JSON Schema
The error.message in a 400 response almost always names the exact field that's wrong. Read it before assuming the whole request is broken.
Streaming Connections Dropping
If non-streaming requests work but streaming ones fail or hang:
- Confirm your HTTP client actually supports server-sent events and isn't buffering the whole response before returning
- Check for a proxy or load balancer in front of your app that buffers responses (common with some reverse proxy default configs)
- Make sure you're parsing
event:anddata:lines correctly and not assuming the whole payload arrives in one chunk
Network and Timeout Issues
If requests intermittently hang or time out with no clear error, check:
- Client-side timeout settings that are too aggressive for long completions
- DNS or firewall rules blocking outbound HTTPS to
api.anthropic.com - Corporate proxies that strip headers or interfere with chunked responses
Out of Credits or Billing Issue
If your account has run out of prepaid credits or has a billing problem, requests fail with a permission-related error rather than a generic server error. Check the billing section of your console directly rather than assuming it's a code issue.
Debug Systematically
Before changing code, isolate the problem:
- Run a minimal
curlrequest with a known-good prompt - If that works, the problem is in your application code (headers, body construction, SDK version)
- If that fails, the problem is your key, account, or the API itself
- Check Anthropic's status page for ongoing incidents before spending time debugging your own code
If You Need More Stability
If you're running Claude in a production app and want a simpler failure surface — one API key per application, clear usage metadata, and a dashboard that shows exactly what's consuming your quota — that's what SubToAPI is built for. It turns your Claude access into a standard HTTPS API with sub_live_... application keys, so debugging "is it my key, my request, or the upstream API" becomes much faster. See the quickstart or the messages docs for setup, or start a free trial.
FAQ
Why does my Claude API key suddenly return 401 after working fine? The key was likely rotated, revoked, or the environment variable holding it wasn't updated everywhere it's deployed. Regenerate the key and confirm it's identical in every environment (local, CI, production).
Is a 529 error my fault? No. A 529 means the API is overloaded and temporarily rejecting requests. Retry with exponential backoff — it's not a bug in your code and doesn't need a code fix beyond proper retry handling.
Why does streaming fail even though normal requests work? Usually a proxy, load balancer, or HTTP client is buffering the response instead of passing chunks through as they arrive. Check for buffering middleware and confirm your client parses server-sent events incrementally. See the streaming docs for a working reference implementation.