Fix 401 Unauthorized in Claude Code and Codex CLI
Step-by-step fixes for the "401 Unauthorized" error when connecting Claude Code or Codex CLI to DeepSeek, OpenRouter, and other providers.
Error output
Common variations
The exact text varies by agent version and provider. Match the status code and the message above.
Quick diagnosis
Run this command and check what the token variable actually contains — the failure is almost always visible there.
echo $ANTHROPIC_AUTH_TOKEN echo $DEEPSEEK_API_KEY $OPENROUTER_API_KEY Common causes
- The API key is wrong, expired, or was regenerated after the config was set.
- The key was exported in an old terminal session and the new value never took effect.
- The provider account has no balance, which some providers report as 401.
- An unexpected ANTHROPIC_API_KEY reroutes traffic back to Anthropic (OpenRouter setups).
Fix by scenario
1 Fails right after the initial setup
- Open a NEW terminal after editing your shell profile — variables from the old session are stale.
- Is the key pasted without extra spaces, quotes, or a trailing newline?
- Does the key start with the expected prefix (sk- for DeepSeek, sk-or- for OpenRouter)?
- Is an old ANTHROPIC_API_KEY still set, overriding the routing?
2 Fails after replacing the API key
- Providers invalidate a key the moment a new one is generated — the old key dies instantly.
- Is the new key exported everywhere the old one was (shell profile, settings.json, CI)?
- Restart the terminal or re-export before retrying.
3 Worked before, now fails
- Did the provider rotate or retire the key? Check the dashboard.
- Is the account balance exhausted? Some providers report 401 instead of 402.
- Did anything touch the shell profile or settings.json recently (new tool, dotfiles sync)?
Agent-specific fixes
Claude Code
- Fix
- Set ANTHROPIC_AUTH_TOKEN to the provider key. With OpenRouter, keep ANTHROPIC_API_KEY="" (explicitly empty). Re-export and open a new terminal.
- Verify
- `claude /status` should show your provider endpoint and a connected state.
Codex CLI
- Fix
- Export the key named by env_key in config.toml (DEEPSEEK_API_KEY or OPENROUTER_API_KEY). Never put the key in the toml itself.
- Verify
- `codex exec "hi"` succeeds and the request appears in the provider dashboard.
Claude Code vs Codex CLI at a glance
| Claude Code | Codex CLI | |
|---|---|---|
| Authentication variable | ANTHROPIC_AUTH_TOKEN | env_key in config.toml |
| Where the key lives | Shell profile or settings.json env block | Exported env var referenced by env_key |
| Verify command | claude /status | codex exec "hi" |
Prevent it from happening again
- Store keys in a password manager and rotate them on a schedule.
- Never commit keys to dotfiles repos or config files.
- Keep a working config snapshot so a broken change is easy to roll back.
Related errors
Related setup guides
Frequently asked questions
I created a new key but still get 401 — why?
The most common cause is a stale terminal session: exports only apply to sessions started after the export. Open a fresh terminal, or re-export and run the verify command again.
Does a Claude Pro or Max subscription fix 401 errors?
No. This setup authenticates with a provider API key and bills to that provider. Subscriptions cannot be combined with a third-party endpoint, so the 401 remains until the key is fixed.
Why do I get 401 with OpenRouter even though the key is correct?
Claude Code falls back to Anthropic authentication when ANTHROPIC_API_KEY is unset or holds a real value. Set it to an explicitly empty string so all traffic goes through OpenRouter.