Fix Codex CLI "exceeded retry limit, last status: 401"
When Codex CLI reconnects five times and ends in 401 Unauthorized, check which credentials it is using, then log out and sign in again in the right order.
exceeded retry limit, last status: 401 Unauthorized, request id: ...The request was rejected at authentication. Retries resend the same credentials, so the loop only ends when you change them. Find out which credentials are in use, then sign in fresh.
[1] Check the version and login state.
$ codex --versioncodex-cli 0.163.0$ codex login statusNot logged inAn API-key login prints Logged in using an API key - ***. If the check fails while reading the file, as in Error checking login status: key must be a string at line 1 column 2, auth.json itself is corrupt. Go to step 4.
[2] Know what a 401 looks like on screen. With a fake key and a local server that always answers 401:
$ codex exec --skip-git-repo-check "hi"ERROR: Reconnecting... 1/5ERROR: Reconnecting... 2/5ERROR: Reconnecting... 3/5ERROR: Reconnecting... 4/5ERROR: Reconnecting... 5/5ERROR: unexpected status 401 Unauthorized: Incorrect API key provided, url: http://127.0.0.1:18401/v1/responsesAfter the first request it resends five more times (the server received six POSTs in total), then gives up. exceeded retry limit, last status: 401 Unauthorized, quoted in user reports, is the same situation worded differently.
[3] Work out which credentials win. Results on 0.163.0:
| Situation | Result |
|---|---|
API key stored in auth.json and OPENAI_API_KEY set | the request carried the stored key |
No auth.json, only OPENAI_API_KEY | codex login status says Not logged in; the codex exec request had no auth header |
No auth.json, only CODEX_API_KEY | codex login status says Not logged in; the codex exec request carried this key |
If you exported a good OPENAI_API_KEY but a stale stored key keeps causing 401, editing the environment will not help. Remove the stored login.
[4] Clear the stored login.
$ codex logoutSuccessfully logged out$ codex login statusNot logged incodex logout deletes auth.json. Login data lives in auth.json under $CODEX_HOME (default ~/.codex) or in the OS credential store, depending on cli_auth_credentials_store (file, keyring, auto, ephemeral) (docs). If codex logout errors or the file is corrupt, move it aside (mv ~/.codex/auth.json ~/auth.json.bak) and log in again.
[5] Sign in again.
$ codex loginThat opens a browser for a ChatGPT account. For an API key, pass it on stdin:
$ printenv OPENAI_API_KEY | codex login --with-api-keyReading API key from stdin...Successfully logged inOn a server without a browser, use codex login --device-auth (beta in the docs). If that fails, the docs suggest copying an auth.json from a machine where browser login worked, or forwarding the callback port (default localhost:1455) over SSH.
[6] Verify, and if it still fails, check the endpoint.
$ codex login statusIf you are logged in and still get the same 401, requests may be going to the wrong address. Inspect model_provider and base_url in config.toml and the OPENAI_API_BASE environment variable. In issue openai/codex#5456, one user reported that removing OPENAI_API_BASE fixed it. It is a single report with no maintainer confirmation, so try it only when the steps above fail.
For config file locations and profiles, see Codex CLI config profiles.