Skip to content
Agent Month

How to fix: 401 authentication error / invalid API key

Last verified: June 2026· All LLM providers

Where this shows up

All LLM providers

How it shows up

The same root cause surfaces in a few different ways. If any of these match, you're in the right place.

  • Every request fails immediately with 401, regardless of model or payload — the request never reaches the model, so latency is near-zero.
  • The same key works from your laptop but fails in CI, staging, or a container.
  • It worked yesterday and broke with no code change — usually a rotated, expired, or revoked key.
  • Only some routes fail, while others succeed — you have more than one key in play and one of them is wrong.
  • The error body says invalid_api_key, authentication_error, Incorrect API key provided, or Unauthorized.

Diagnose it first

Confirm which cause you actually have before changing anything — most wasted time here comes from fixing the wrong one.

CheckWhat the result tells you
Print the key length and last four characters at startup (never the whole key).Empty or much shorter than expected means the variable never loaded — a .env file not read, or a missing secret in the deploy environment.
Call the provider directly with curl using the same key.If curl works and your app does not, the problem is in the SDK config or header, not the key itself.
Check for leading/trailing whitespace or quotes in the environment value.A trailing newline from a copied secret or quotes preserved by a shell will produce a 401 for a key that is otherwise valid.
Confirm which header the SDK is actually sending.Sending a key in Authorization: Bearer to a provider that expects x-api-key (or the reverse) always returns 401.
Check whether the key is scoped to the project, org, or model you are calling.A valid key with no access to that workspace or model returns 401 or 403 depending on provider — the key is real but not entitled.

The fix

  1. 1Confirm the key is set in the environment and loaded — not hardcoded, not an empty string.
  2. 2Check you’re not setting two conflicting credentials at once (e.g. both an API key and an auth token) — some SDKs send both and the API rejects it.
  3. 3For OAuth/bearer tokens, send them in the Authorization: Bearer header, not the API-key header.
  4. 4Verify the key hasn’t been revoked and has access to the model/workspace you’re calling.
  5. 5Rotate the key if it may have leaked, and move it into a secrets manager.

Provider-specific behaviour

The error means roughly the same thing everywhere, but each provider signals it differently.

OpenAI
Expects Authorization: Bearer . Project-scoped keys (sk-proj-…) are bound to one project — if you also send OpenAI-Organization or OpenAI-Project headers, they must match the key's project or the call is rejected. The JSON body carries a machine-readable error.code such as invalid_api_key.
Anthropic
Expects x-api-key: , **not** Authorization: Bearer. This is the single most common cause of a 401 when porting code from an OpenAI-shaped client. The anthropic-version header is also required; omitting it produces a different 400-class error, so a 401 here is genuinely the key or its header.
Google (Gemini)
Accepts the key as an x-goog-api-key header or a ?key= query parameter. Keys can be restricted by referrer or IP in the Google Cloud console — a key that works locally and fails from a server is usually hitting an API-key restriction, not an invalid key.
Azure OpenAI
Uses the api-key header for key auth, or an AAD bearer token for identity-based auth — the two are not interchangeable. A 401 here often means the resource endpoint, deployment name, or api-version does not match the key's resource.
AWS Bedrock
Does not use API keys at all — it authenticates with SigV4 from the standard credential chain. A 401/403 means expired STS credentials, a missing region, or an IAM policy without bedrock:InvokeModel, not a bad key string.

What doesn't work

Common fixes for this error that look right and aren't.

  • Regenerating the API key as the first step.

    If the cause is a missing environment variable or the wrong header, a new key fails identically — and you have now invalidated the old key for every other service still using it correctly.

  • Hardcoding the key "just to test".

    It usually proves the key is fine while masking the real config bug, and the temporary key reliably survives into a commit. If you must isolate it, use curl outside the codebase instead.

  • Adding a retry loop around the 401.

    401 is a deterministic authentication failure, not a transient one. Retrying cannot succeed, and it turns one clear error into a burst of identical failures that is harder to read in logs.

Prevent it

Load keys from a secrets manager, never commit them, and scope keys narrowly per service.

Common variations and related errors

You'll usually hit this same root cause under a few different names. Same fix.

  • "401 unauthorized"
  • "invalid API key"
  • "Incorrect API key provided"
  • "Authentication credentials not found"
  • "expired token"
  • "invalid_api_key"

Frequently asked questions

What causes “401 authentication error / invalid API key”?

The API key is missing, malformed, revoked, or sent the wrong way (e.g. an OAuth token in the API-key header).

How do I prevent “401 authentication error / invalid API key” from recurring?

Load keys from a secrets manager, never commit them, and scope keys narrowly per service.

Why does my API key work locally but return 401 in production?

Almost always an environment difference rather than the key. The usual causes: the secret was never added to the production environment, the deploy platform injects it under a different variable name, the value picked up a trailing newline when it was pasted, or the key is IP/referrer-restricted and your server's address is not on the allow-list. Log the key length and last four characters at startup in both environments and compare.

What is the difference between a 401 and a 403 from an LLM provider?

401 means the request was not authenticated — the credential is missing, malformed, expired, or sent in the wrong header. 403 means you were authenticated successfully but are not authorised for that specific action, such as a valid key calling a model your organisation has not been granted access to. If you see 403, stop checking the key and start checking entitlements and IAM policy.

Can a rate limit cause a 401?

No. Rate limiting returns 429 and quota exhaustion typically returns 429 or a billing-specific error. If you are getting 401 the request is being rejected before any usage accounting happens, so the cause is authentication, not volume.