Claude Code Errors, Decoded by Where the Request Failed: Invalid API Key, 401, Credit Balance, 529, Unable to Connect
Claude Code error messages provide a starting point for investigation. Run /status to see which credential is active, then match the message to the stage that failed: no credential, a rejected credential, billing or rate limits, server capacity, or the network path. Fixes follow Anthropic's error reference, rewritten so you never print a key to your terminal.
1. Start with /status, not a reinstall
Claude Code's error messages are short, and Anthropic's error reference gives one starting point for all of the authentication-related ones: run /status at any time to see which credential is currently active. When both a login and an API key are configured, /status marks the one that is not in use. Look at three things. Is there an API key or Auth token row, and which variable does it name? Is there an Anthropic base URL row? That row only appears when a gateway address is set, so seeing it when you did not expect it is already a finding. And is the login method the account you think you are using? The reason to do this first is simple: if an approved key from your environment is the active credential, running /login again does not replace it. The official 401 guidance says this directly. Reinstalling the CLI does not touch your shell environment either, so the same stray variable comes straight back.
/status
# List ANTHROPIC_* variable names only, without printing their values
env | grep -oE "^ANTHROPIC[A-Z_]*"2. Why a stray key beats your subscription login
When several credentials are present, Claude Code picks one in a fixed order, according to its authentication documentation: cloud provider credentials when a variable such as CLAUDE_CODE_USE_BEDROCK is set, then ANTHROPIC_AUTH_TOKEN (sent as an Authorization: Bearer header), then ANTHROPIC_API_KEY (sent as an X-Api-Key header), then the output of an apiKeyHelper script, then CLAUDE_CODE_OAUTH_TOKEN, then Anthropic profile and federation credentials, and last of all the subscription login from /login. In interactive mode you are asked once whether to use an ANTHROPIC_API_KEY found in your environment, and your answer is remembered; in non-interactive mode (-p) the key is always used when present. So a key you exported months ago for a script can quietly take over every session: if it was revoked you see Invalid API key, and if its organization was disabled you see a 401. The documented way back is unset ANTHROPIC_API_KEY, removing the export from your shell profile, and confirming in /status that the login is now active. Watch for keys you never set by hand, too: direnv, dotenv shell plugins and IDE terminals can load one from a .env file in your project.
unset ANTHROPIC_API_KEY
# then delete the export line from ~/.zshrc or ~/.bashrc and start claude from a new terminal
# Windows PowerShell
Remove-Item Env:ANTHROPIC_API_KEY3. Diagnose without putting your key on screen
Many troubleshooting guides, including one suggestion in the official error reference, tell you to run env | grep ANTHROPIC. That prints the full value of every matching variable, and terminal output has a way of ending up in screenshots, screen recordings, pasted support threads and the scrollback of shared machines. You only need two facts to troubleshoot: which variables exist, and where they come from. You never need the value. List names only, and when you need to know whether one particular variable is set, ask a yes-or-no question instead of echoing it. If you suspect a stray line break or space in the key, current versions of Claude Code describe the problem after Invalid API key, naming the character position; in that case the API never received the key at all, and copying it again cleanly from the Console fixes it. A base URL can contain sensitive parameters; check only the hostname rather than printing the full value. And if a key has already appeared in a screenshot or a chat, revoke it in the Console and create a new one rather than hoping nobody noticed.
env | grep -oE "^ANTHROPIC[A-Z_]*"
[ -n "$ANTHROPIC_API_KEY" ] && echo "ANTHROPIC_API_KEY is set" || echo "ANTHROPIC_API_KEY is not set"
[ -n "$ANTHROPIC_AUTH_TOKEN" ] && echo "ANTHROPIC_AUTH_TOKEN is set" || echo "ANTHROPIC_AUTH_TOKEN is not set"
[ -n "$ANTHROPIC_BASE_URL" ] && echo "ANTHROPIC_BASE_URL is set" || echo "ANTHROPIC_BASE_URL is not set"4. Rejected credentials: Invalid API key versus 401
Both messages read like a bad key, and the official reference treats them differently. Invalid API key · Fix external API key means the key from ANTHROPIC_API_KEY or an apiKeyHelper script was rejected by the API, or Claude Code blocked it before sending because it contained a character an HTTP header cannot carry. Check for typos and confirm on the Console's keys page that the key has not been revoked. If it comes from apiKeyHelper, ask the administrator to check its configuration and credential source without running a helper that prints the secret to the terminal. API Error: 401 Invalid authentication credentials means the API recognized the credential's format but rejected the account or organization behind it: a credential that was recently revoked, an organization that was disabled or removed your access, or a deactivated account. Anthropic is explicit that an expired token is not the cause. If /status shows an active API key, rotate it in the Console or unset it to fall back to your subscription; if it shows only your login, run /login once; if the same login keeps failing, the account or organization is no longer active and an organization admin has to restore access. Expired logins have their own messages, such as Login expired or OAuth token revoked, and a fresh /login clears them.
5. Accepted but not allowed: credit balance, 429 and plan limits
Credit balance is too low has two possible causes. Either your Console organization has run out of prepaid credits, in which case you add credits on the Console billing page and, as the documentation suggests, consider auto-reload and per-workspace spend caps so one project cannot drain the whole balance. Or you have a Pro, Max, Team or Enterprise plan and an approved ANTHROPIC_API_KEY in your environment is sending your requests through that key's organization instead; the API key row in /status shows this, and unsetting the variable and relaunching claude puts you back on your plan. Request rejected (429) is a rate limit on your API key, Amazon Bedrock project or Google Cloud project, unrelated to balance. Confirm the active credential first, since the documentation warns that a stray low-tier key can carry your requests instead of your subscription; then check the active limits in your provider console, and for scripted runs reduce parallel subagents or pick a smaller model with /model. Subscription users can also see plan messages such as You've hit your session limit or You've hit your monthly spend limit. Those name a reset time or where the limit is raised, and /usage shows each window and when it resets.
6. Accepted but not served: 500 and 529
API Error: 500 reports an unexpected failure inside the API; the documentation says it is not caused by your prompt, settings or account. API Error: Repeated 529 Overloaded errors means the API is temporarily at capacity for all users, and Claude Code has already retried several times before showing it. Anthropic states plainly that a 529 is not your usage limit and does not count against your quota. What to do: check status.claude.com for an active incident, wait a few minutes and send again (your message is still in the conversation, so typing try again is enough for a long prompt), or switch models with /model, because capacity is tracked per model. The status page the error names depends on how you connect: Bedrock, Google Cloud and Microsoft Foundry configurations name their own status pages, and a custom ANTHROPIC_BASE_URL names the gateway host. One gateway-only case is worth knowing: if every request fails with a 500, a 401, a model error or a dropped connection behind a gateway, the documentation suggests setting ENABLE_TOOL_SEARCH=false to rule out a gateway that rejects the tool search fields Claude Code sends by default.
7. Connection failure: Unable to connect to API
These messages mean the TCP connection failed or never completed, and the code in parentheses points the way: ConnectionRefused means nothing answered at the address, ENOTFOUND means the hostname did not resolve, and ECONNRESET means the connection was dropped. The documented first step is to run curl -I against the API host from the same shell you launch claude from. If curl succeeds and Claude Code still fails, the cause is usually between the runtime and the network. One easy-to-miss cause is a leftover ANTHROPIC_BASE_URL pointing at a local gateway or old relay that is no longer running: when it is set, Claude Code sends model requests there instead of to the API, so curl reaches the API while Claude Code reports Connection refused. Check your shell profile and also the env block of your Claude Code settings files; the documentation notes that a value set there can override a shell export. On Linux and WSL, check /etc/resolv.conf for an unreachable nameserver. Then start claude from a fresh terminal.
curl -I https://api.anthropic.com
# If you route through a gateway or relay, test your own address
curl -I "$ANTHROPIC_BASE_URL"
# Look for a leftover base URL in settings files (list matching filenames, not their contents)
grep -l "ANTHROPIC_BASE_URL" ~/.claude/settings.json .claude/settings.json .claude/settings.local.json 2>/dev/null8. Using a gateway or cocodot: verify before you save anything
When you run Claude Code through an Anthropic-compatible gateway or relay, the official gateway guide recommends verifying the connection before persisting anything. Export ANTHROPIC_BASE_URL and the credential variable in your shell, then send a one-token request straight to the gateway. A JSON response that starts with {"id":"msg_ means the URL and credential work. An error naming an unknown model also proves the credential was accepted, because the gateway authenticated the request before rejecting the model name. A 401 means the credential was rejected. Which variable to use depends on the gateway: if it asks for a bearer token or an Authorization header, use ANTHROPIC_AUTH_TOKEN; if it asks for an API key or x-api-key, use ANTHROPIC_API_KEY. A credential in the wrong variable lands in a header the gateway does not read and fails with the same 401. Once the test passes, start claude from that shell and confirm in /status that the Anthropic base URL row shows the gateway. The guide also warns: do not put the credential in a project's .claude/settings.json, because that file is committed and shared with everyone who clones the repository. To connect to cocodot, set ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN as described on /hub/claude-code. New users complete identity verification before calling the API, and the free trial credit covers only some lower-priced models. Listed Claude / GPT / Gemini rates are at or below the official list price; check the pricing page for each model's current rate.
MODEL="a-model-name-your-gateway-serves"
curl -sS -w '\n%{http_code}\n' -X POST "$ANTHROPIC_BASE_URL/v1/messages" \
-H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d "{\"model\": \"$MODEL\", \"max_tokens\": 1, \"messages\": [{\"role\": \"user\", \"content\": \".\"}]}"Claude Code errors by the stage that failed
| Error message | Stage that failed | First thing to do |
|---|---|---|
| Not logged in · Please run /login | No credential available to the session | Run /login, or export the variable in the shell that launches claude |
| Invalid API key · Fix external API key | The key from ANTHROPIC_API_KEY or apiKeyHelper was rejected, or blocked locally for an unsendable character | Confirm the key is not revoked in the Console; list variable names to find a stale one |
| API Error: 401 Invalid authentication credentials | The API rejected the account or organization behind the credential; behind a gateway, it is the gateway's message | Run /status to see whether a key or your login is active, then fix that one |
| Credit balance is too low | Console prepaid credits ran out, or a stray key replaced your subscription | Check the API key row in /status; add credits only if you meant to use a key |
| API Error: Request rejected (429) | The key or cloud project hit its configured rate limit | Confirm the active credential; reduce parallel subagents |
| API Error: Repeated 529 Overloaded errors | API temporarily at capacity for everyone; not your quota | Check status.claude.com, retry later, or switch models with /model |
| Unable to connect to API (with a code such as ConnectionRefused or ENOTFOUND) | The TCP connection never completed | Run curl -I from the same shell; check for a leftover ANTHROPIC_BASE_URL |