Where keys break in real life
Keys rarely fail in the code that uses them. They fail on the way there: a copy that grabbed half the string, an .env entry whose quotes became part of the value, a CI secret saved with a trailing newline, a deploy that shipped staging's key to production.
The other family is administrative. The key was revoked or rotated, it belongs to a different project than the one you're calling, or your server's IP isn't on the allowlist your org enforces. Every one of these returns the same 401 — which is why you diagnose by layer instead of by guess.
The response
HTTP/1.1 401 Unauthorized
{
"error": {
"message": "Incorrect API key provided: sk-abc***. You can find your API key in your dashboard.",
"type": "invalid_request_error",
"code": "invalid_api_key"
}
}
That body is representative, not a transcript. The masked fragment echoes what you sent: if it doesn't match the key you meant to load, the environment is the bug. Worth knowing: a 401 can also mean missing org membership or an IP outside the allowlist, and a 403 reading "Country, region, or territory not supported" is geography, not authentication.
Ninety-second diagnosis
# 1. Is the env var what you think it is?
echo "len=${#OPENAI_API_KEY} head=${OPENAI_API_KEY:0:4} tail=${OPENAI_API_KEY: -4}"
# 2. Does the key itself pass auth?
curl -s https://api.openai.com/v1/models \
-H "Authorization: Bearer $OPENAI_API_KEY"
Read the echo first. Length zero means the variable never loaded. A tail showing a quote or odd character means the env file is malformed. If the echo looks right and the curl returns a model list, the key works and your app is loading something else, usually a stale process. If the curl 401s on a key minted minutes ago, stop staring at the string and check project scope, org membership, and the allowlist.
Keep it from recurring
Three habits retire this bug. Keep keys in a secrets manager, not in files that travel with the repo. Issue one key per environment, so a staging leak can't touch production. And run a startup self-check, one cheap authenticated call, so a dead key fails the deploy, not the first customer request. With auth boring again, the interesting question is spend: GPT-5 runs $1.25 in and $10 out per million tokens, and the rankings show what else that budget buys.