Codex sign-in fails: which stage actually broke
Sign-in can fail at one of several distinct stages — the browser step, the localhost callback, or the token exchange — and each needs a different response. This guide helps you identify which stage broke before changing anything.
Start here
Identify the exact line your client printed — a token-exchange error, a localhost:1455 callback failure, or no error at all — because each points to a different stage.
What you see
The client prints one of these, or nothing at all:
Token exchange failed: error sending request for url (https://auth.openai.com/oauth/token)
Starting local login server on http://localhost:1455. If your browser did not open, navigate to this URL to authenticate:
GET http://localhost:1455/auth/callback?code=redacted&scope=openid profile email offline_access&state=redacted
Status 500 / Internal Server Error
Or you land on the “Sign in to Codex CLI with ChatGPT” screen and it never advances. In the remote and headless cases the browser may complete on one machine while the client, running on another, stays signed out — because the callback never reaches the listener that is actually running.
What it usually means
Sign-in is not one step; it is a short chain, and each link fails differently:
- The browser step — a browser is opened (or should be) and the account is authenticated.
- The local callback — the browser returns to a listener the client started on
localhost:1455. If that listener is unreachable (port conflict, firewall, or the listener living on a different machine), the flow breaks here. This is the stage the official documentation says breaks first in remote, headless and restricted-network environments. - The token exchange — the client turns what it received into a usable session credential. A failure here shows the
Token exchange failed: ...line.
What the product’s own source code does about the port. First-party source code on the product’s default branch (codex-rs/login/src/server.rs) defines const DEFAULT_PORT: u16 = 1455; and, immediately after it, const FALLBACK_PORT: u16 = 1457; with the comment // Keep in sync with the Codex CLI Hydra redirect URI allow-list. The redirect URI is built from the port that actually got bound: let redirect_uri = format!("http://localhost:{actual_port}/auth/callback"); — not a hardcoded value. The binding routine tries 127.0.0.1:{port}; if that address is in use it sends a cancel request to the previous listener, retries up to 10 times at 200 ms intervals, and only then, if it is still on the default port, moves to the fallback port while emitting a warning that the default login callback port is unavailable.
The practical consequence: a firewall rule that opens only 1455 is insufficient if 1455 is already taken — the client may quietly move to 1457, and the port you need to allow is the one your client actually printed. Caveat: these facts describe the default branch and may differ from the version you have installed.
Quick checks
- Did a browser open at all? If not, you are in the remote/headless case below (#2021, #4265).
- Did the callback reach the right machine? On WSL, Remote-SSH or a headless server, the listener runs on the remote host’s
127.0.0.1:1455while your local browser is sent tolocalhost:1455(#4265, #4562). They are different machines. - What is the exact terminal line? A
Token exchange failedline is a different branch from alocalhost:1455callback500. - Check state without guessing:
codex login statusprints the active authentication mode (the CLI reference documents it as “Show login status.”), and the documentedcodex doctorruns diagnostics for startup, connectivity and performance.
Fixes, by branch
If the browser never opens or the callback lands on the wrong machine
This is the remote/headless case. The listener is on the server’s 127.0.0.1:1455, not on your laptop or phone, so the redirect to localhost:1455 cannot reach it (#2021, #4265, #4562). Two documented escapes exist:
- Forward the port so your local
localhost:1455reaches the remote listener:ssh -L 1455:localhost:1455 user@remote(documented in the official auth docs). Then complete the browser flow locally. - Or use the device-code path, below.
If the callback to localhost:1455 fails
If you see the GET http://localhost:1455/auth/callback?... line followed by Status 500 / Internal Server Error (#5283), the listener is up but the exchange is not completing — usually a local firewall or other network setting between browser and listener. A maintainer’s closing comment on #5283 recommended the headless device-authentication technique for exactly this situation (a routing recommendation, not a diagnosis). Try the device-code path below, and check whether a firewall rule opens the actual port printed.
If you see a token-exchange error
The Token exchange failed: error sending request for url (https://auth.openai.com/oauth/token) line (#6413, #4562) means the client could not complete the exchange with the auth endpoint. Reported environments include Windows 11 + WSL and plain Linux; it is not documented as platform-independent. No maintainer root cause for this class was found in the sources opened for this guide — the closest maintainer input is a diagnostic suggestion (see “What not to do”), not a fix.
If you are stuck on the “Sign in with ChatGPT” screen
#2763 reports the flow spinning indefinitely on the sign-in screen. One reporter observed that signing in worked under bash but not their fish shell, suggesting a shell- or environment-variable difference — this is a single reporter’s hypothesis, not a confirmed cause, and it should be tested rather than treated as fact.
The documented headless / remote escape hatch
- Device code:
codex login --device-authruns the device-code flow instead of launching a browser. The CLI source defines--device-authas mapping to the device-code login path, and a maintainer on #5283 recommended it for network-blocked cases. Prerequisite (per the official auth docs): device-code login must be enabled in ChatGPT security settings or workspace permissions; if the server does not enable it, Codex falls back to the browser flow. - API key instead of ChatGPT:
printenv OPENAI_API_KEY | codex login --with-api-keyreads the key from stdin (the CLI source defines--with-api-keythis way). An access token can be supplied similarly viacodex login --with-access-token. - Corporate TLS inspection: the official auth docs describe setting
CODEX_CA_CERTIFICATEto a PEM bundle before logging in (falling back toSSL_CERT_FILEwhen unset). - Check state:
codex login statusreports the active mode;codex doctorcovers connectivity diagnostics.
What not to do
- Do not delete your whole Codex configuration.
rm -rf ~/.codexremoves the entire configuration and session directory, not just credentials. It appears in community material and is not a step this guide recommends. - Do not treat
rm ~/.codex/auth.jsonas a fix. A maintainer on #6413 suggested trying it as a way to help isolate the root cause (“would help isolate”) — that is a diagnostic suggestion, not a confirmed fix. It deletes your stored credentials and is only reversible by signing in again. If you try it, move the file aside rather than deleting it, and understand it is a diagnostic step, not a remedy. - Do not copy
~/.codex/auth.jsonbetween machines as a routine fix. The official auth docs describe a copy-auth.jsonfallback for headless setups, but it moves a live credential off one machine; do it only with that understanding and the documented caveat that it does not apply when credentials live in an OS credential store. - Do not run
codex login --api-keyas a current command. The CLI source marks the bare--api-keyflag as hidden and deprecated; it exits with guidance to use--with-api-key. - Do not paste tokens or credentials into a public issue when asking for help.
- Do not name or assume a specific OS credential store. No source in this research found macOS Keychain, Windows Credential Manager or Linux Secret Service named for Codex; the official text only says “your operating system credential store.”
How to tell it worked
You are done when codex login status reports a signed-in mode, the client reaches a usable signed-in state on the network you normally use, and a normal prompt works. Because some of these failures are intermittent (and a firewall may only block the port that was actually chosen), give it more than one attempt before concluding.
If it is still failing
Collect: the client version, the operating system and whether you are in WSL/Remote-SSH/a headless server, the plan type, the exact terminal line, whether the browser opened, and which port (1455 or 1457) was printed. A maintainer’s recommendation for the network-blocked case is to use device-code authentication rather than to keep retrying the browser flow.
Known limits of this guidance
- Evidence level: reported. This is built from public GitHub issue reports, a maintainer’s diagnostic suggestion, and first-party source-code inspection of the login server and CLI flag definitions — not from a reproduction by this site.
- The canonical
developers.openai.com/codex/authpage returned HTTP 403 during research, so the documented details carried from it (per-OS credential-store names and the exact headless command spelling beyond what the source code shows) are not asserted here. macOS Keychain, Windows Credential Manager and Linux Secret Service are deliberately not named because no source in this research found them for Codex. - No maintainer root cause was found for the token-exchange failure class. The #6413 comment is a diagnostic suggestion; the #5283 comment is a routing recommendation.
- The
os error 10013Windows port-exclusion class was not opened in this research and is not covered here. - No fix version can be named. Reported versions span 0.19.0 to 0.63.0; the documentation and behaviour may have changed across that range.
- The source-code facts describe the product’s default branch and may differ from the version you have installed.
ERR_CONNECTION_REFUSED/ “This site can’t be reached” appear in third-party write-ups but were not found verbatim in any primary source opened here, so they are not claimed.
Sources
Each source lists what it is used to support. Sources are re-read on the review schedule, not continuously.
codex-rs/login/src/server.rs (default branch)
The login callback port mechanism: DEFAULT_PORT 1455 and FALLBACK_PORT 1457, that the redirect URI is built from the port actually bound, and that the listener retries up to 10 times at 200 ms intervals before falling back to 1457 with a warning when the default port is taken.
codex-rs/cli/src/main.rs (default branch)
CLI flag definitions: --with-api-key reads the key from stdin, --with-access-token reads an access token from stdin, --device-auth maps to the device-code login path, the status subcommand is documented as 'Show login status.', and the bare --api-key flag is hidden and deprecated.
Using Codex with your ChatGPT plan (OpenAI Help Center)
The documented sign-in path ('Sign in with your ChatGPT account') and that 'codex doctor' runs diagnostics covering startup, connectivity, and performance.
Codex authentication (developers.openai.com)
The documented sign-in methods (Sign in with ChatGPT and Sign in with an API key), the headless device-code path, the CODEX_CA_CERTIFICATE corporate-TLS variable, the ssh -L 1455:localhost:1455 port-forward, and that credentials are cached in ~/.codex/auth.json or an OS credential store. Read via mirror during research; the canonical page returned HTTP 403.
Codex CLI reference (developers.openai.com)
That 'codex login' opens a browser for the ChatGPT OAuth flow, --with-api-key reads a key from stdin, 'codex login status' prints the active authentication mode, and 'codex logout' clears saved credentials. Read via mirror during research.
Token exchange failed on Windows 11 + WSL (openai/codex #6413)
The verbatim token-exchange error on Codex 0.4.38 / Windows 11 / WSL, a maintainer's diagnostic suggestion to try 'rm ~/.codex/auth.json' (a suggestion, not a confirmed fix), and that the issue is closed as a duplicate of #4562.
WSL / remote sign-in failure (openai/codex #4562)
The reporter's explanation that the callback URL is generated inside WSL using localhost and cannot reach the plugin, and a quoted client log line 'CLI: Token exchange error: error sending request for url (https://auth.openai.com/oauth/token)'.
localhost:1455 callback returns 500 (openai/codex #5283)
The verbatim 'GET http://localhost:1455/auth/callback?...' followed by 'Status 500 / Internal Server Error', and a maintainer's closing recommendation to use headless device authentication when the browser flow is blocked by local firewall or network settings.
Browserless machine cannot reach localhost:1455 (openai/codex #2021)
The verbatim prompt 'Starting local login server on http://localhost:1455. If your browser did not open, navigate to this URL to authenticate:' and the remote-redirect problem where the callback targets the server's localhost, not the phone or local browser.
Remote-SSH callback listener unreachable (openai/codex #4265)
That the CLI/extension spawns the callback listener on 127.0.0.1:1455 of the remote host while the local browser is redirected to localhost:1455, so the flow never completes.
Stuck on 'Sign in with ChatGPT' screen (openai/codex #2763)
The 'stuck on the sign-in screen' case and one reporter's observation that signing in worked under bash but not their fish shell (a hypothesis, not confirmed).
Related guides
How this page is checked
- Evidence level
- Reported - based on public reports, not reproduced here
- Last reviewed
- 2026-09-20
- Content updated
- 2026-09-20
- Full version scope
- Reported across codex-cli 0.19.0 through 0.63.0 and the VS Code extension 0.4.14 through 0.4.38, on Windows 11 + WSL, Linux, macOS, and remote/headless environments. The scope across other versions and platforms is not established, and no fix version is named.
- Symptoms indexed
-
- You ran codex login or clicked sign-in, a browser step appeared to complete, but the client never reaches a signed-in state
- The browser never opens at all, or opens but lands on a page that will not load
- A token-exchange error appears in the terminal after the browser step
- You are stuck on the 'Sign in with ChatGPT' screen
Reviewer note
Built from public GitHub issue reports, a maintainer's diagnostic suggestion, and first-party source-code inspection of the login server and CLI flag definitions. No reproduction was performed here. The maintainer comment on #6413 is a diagnostic suggestion, not a confirmed fix, and the canonical developers.openai.com auth page returned HTTP 403 during research, so several documented details are carried from mirrors and not byte-verified.