# OpenAI 401 after rotating your key: hunt the stale copy across every layer

## The symptom

`401 Incorrect API key provided` persists after you generated a new key and confirmed it works from the dashboard or a manual curl. The new key is good. Something between your code and the API is still sending the old one.

## Confirm the cause

The request carries a key, and it is not the new one. Find which layer injects it. Check in order, innermost first:

1. **Hardcoded value.** Grep the codebase for the old key prefix (`sk-proj-` plus the first few characters; never paste the full key into logs or chat). Config files, committed `.env` files, and copy-pasted client constructors are the usual suspects.
2. **Environment shadowing.** The shell, the container runtime, the CI job, and the process manager each have their own env. Print the key's length and first/last 4 characters from inside the running process, not from your laptop shell. If they differ, you found the layer.
3. **Container image layers.** A key baked into an image at build time survives every deploy until the image is rebuilt. Check the Dockerfile and build args.
4. **Secret manager caching.** Vault, AWS Secrets Manager, and friends cache reads. Confirm the stored version matches the new key and that the app re-read it after rotation (many only read at startup).
5. **SDK and proxy defaults.** A client constructed with an explicit key beats the env var; a proxy or gateway (base_url override) may inject its own key upstream. Check both.

## The fix

Replace the stale copy at the layer you found, then restart or redeploy so the new value is actually loaded. After that, revoke the old key in the dashboard so a missed layer fails loudly instead of silently working with a key you meant to kill.

## Verify the fix

From the exact runtime (container, CI job, deployed service), run the cheap `GET /v1/models` call and confirm 200. Then confirm the old key is dead: a request with the old key must now 401. If it still works, you have not finished revoking.