← Blog

Claude API Error 401 Unauthorized: How to Fix It

2026-10-07 · 5 min read · SubToAPI Team

A 401 Unauthorized error from the Claude API almost always means Anthropic's servers either didn't receive an API key at all, received one in the wrong format, or received a key that's no longer valid. It is not a rate limit, a billing issue, or a model availability problem — those return different status codes. The fix is usually fast once you know where to look.

This article walks through the exact causes in order of likelihood, with the commands to check each one, so you can go from "401" to a working request in a few minutes.

Step 1: Confirm the header format is correct

The Claude API expects your key in a specific header, not a standard Authorization: Bearer header in most direct Anthropic SDK setups. If you're calling Anthropic's API directly, the key goes in x-api-key, and you also need an anthropic-version header. A common cause of 401s is sending the key as Authorization: Bearer sk-ant-... when the endpoint expects x-api-key: sk-ant-..., or omitting the version header entirely so the request gets rejected before it even checks the key.

Check your raw request:

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-3-5-sonnet-20241022",
    "max_tokens": 100,
    "messages": [{"role": "user", "content": "Hello"}]
  }'

If you're using a proxy or wrapper service that exposes a Bearer-token style API (like SubToAPI, see below), the header convention is different again — always check the specific docs for the service you're calling, not just the general Claude API docs.

Step 2: Check for whitespace, quotes, and truncation

Copy-pasting keys into .env files or shell exports is the single most common source of 401s that "should work." Look for:

A quick sanity check:

echo -n "$ANTHROPIC_API_KEY" | wc -c

Compare the length to what you see in your dashboard. If it's shorter than expected, something got truncated.

Step 3: Verify the key is actually loaded into the environment

This is especially common in local development. You export a key in one terminal tab, then run your script from a different tab or a different shell session where the variable was never set.

echo $ANTHROPIC_API_KEY

If this prints nothing, your application is sending an empty string or undefined as the key, which Anthropic will reject with a 401. In Node.js, double-check you're loading .env before any API client is instantiated:

require('dotenv').config();
const apiKey = process.env.ANTHROPIC_API_KEY;

if (!apiKey) {
  throw new Error("API key not found in environment");
}

Adding that explicit check at startup saves hours of debugging later — you'll fail fast with a clear message instead of a confusing 401 three calls deep into your app.

Step 4: Check if the key was revoked or rotated

Keys get revoked when:

If a key worked yesterday and doesn't today with no code changes, assume it was rotated or revoked and generate a fresh one. Don't spend time debugging headers if the key itself is dead.

Step 5: Make sure you're not mixing keys between environments

If you have separate keys for development, staging, and production, a 401 can simply mean the wrong key loaded for the wrong environment — for example, a production deploy pulling a staging secret because of a misconfigured CI variable. Log (safely, redacted) the first 8 characters of the key your app is actually using at runtime to confirm it matches what you expect.

If you're using a Claude API gateway instead of calling Anthropic directly

If your stack is built on an API gateway that wraps Claude access — for issuing per-application keys, tracking usage, or giving teammates their own credentials — the troubleshooting steps are similar but the header and key format will differ from Anthropic's native API. For example, with SubToAPI you authenticate with a standard Bearer token using keys prefixed sub_live_...:

curl https://api.subtoapi.app/v1/messages \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-3-5-sonnet-20241022",
    "max_tokens": 100,
    "messages": [{"role": "user", "content": "Hello"}]
  }'

A 401 here means the same categories of problems — missing or malformed header, revoked key, wrong environment — just under a different auth scheme. If you're setting this up for the first time, the quickstart walks through key creation and your first request end to end, and the Messages API reference documents the exact header and body format expected.

A quick checklist before you keep debugging

Work through these in order and the 401 almost always resolves. If it doesn't, the key is probably fine and the problem is elsewhere in the request — check for a malformed JSON body or missing required fields, which can sometimes surface as auth-adjacent errors depending on the client library you're using.

Questions

Does a 401 mean I'm being rate limited? No. Rate limits return a 429 status code. A 401 specifically means authentication failed — the key was missing, malformed, or invalid, not that you've sent too many requests.

Can an expired free trial cause a 401? It depends on the provider. With Anthropic's native API, billing issues usually return a different error than 401. With gateway services, an expired trial or canceled subscription can return 401 or 403 depending on how they implement access control — check the specific service's status page or pricing page for details on what happens after a trial ends.

I regenerated my key and it still doesn't work — why? Check that your application actually restarted after you updated the environment variable or secret. Many frameworks cache environment variables at process start, so a regenerated key won't take effect until you redeploy or restart the running process.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →