Codex CLI Login Stuck at "Finish signing in via your browser" — A Managed Daemon Was Holding Port 1455
I launched my usual Codex CLI and the TUI would not move past this screen:
Welcome to Codex, OpenAI's command-line coding agent
Finish signing in via your browser
If the link doesn't open automatically, open the following link to authenticate:
https://auth.openai.com/oauth/authorize?response_type=code&client_id=app_EMoamEEZ73f0CkXaXp7hrann&redirect_uri=http%3A%2F%2Flocalhost%3A1455%2Fauth%2Fcallback&...
On a remote or headless machine? Press esc and choose Sign in with Device Code.
Press esc to cancelThe browser side had reached the ChatGPT consent page and I had clicked “Continue,” but the TUI kept waiting. Here is how I traced the cause and what finally cleared it.
What I checked
First, I confirmed whether the login itself had actually gone through.
codex login status
# => Logged in using ChatGPT~/.codex/auth.json had also been touched at 11:31 on the same day, so tokens were on disk. The OAuth exchange had completed; the TUI simply was not picking it up.
Next, I looked at who was bound to the OAuth callback port localhost:1455.
lsof -i :1455The listener was not the codex TUI I had open (PID 28816). It was an 18-hour-old background process, codex app-server --managed-daemon (PID 21226).
Codex CLI is set up so that several clients (the TUI, the VS Code extension, the desktop app, and so on) can share the same authentication state through a resident --managed-daemon app-server. When an existing daemon is already bound to the OAuth redirect port, a later TUI cannot receive its own callback and the “Finish signing in via your browser” prompt never clears.
Order I tried
I tried the following top to bottom, and step 3 was the one that worked.
1. Press Esc and relaunch codex
Since the credentials were already in place, restarting the TUI usually gets you into a normal session. This time it just returned me to the same waiting screen.
2. Device-code flow with codex login --device-auth
I tried the device-code flow, which does not depend on a browser redirect.
codex logout && codex login --device-authThe ChatGPT consent screen at auth.openai.com/sign-in-with-chatgpt/codex/consent then displayed this warning:
Enable device-code sign-in for Codex, Excel, PowerPoint, and Word in your ChatGPT security settings, then run
codex login --device-authagain.
Device-code sign-in requires an opt-in on the ChatGPT security settings side. I did not want to change that setting just to work around this login, so I stopped here.
3. Kill the daemon holding port 1455, then codex login
Stop the resident process that owns the port, then run the normal OAuth login again.
lsof -i :1455
# => codex app-server --managed-daemon and possibly others, on PIDs different from the TUI
kill 21226 68415
codex loginThe PIDs to kill depend on your environment; check what is actually listening with lsof -i :1455 before killing anything. If the Codex desktop app or a browser extension is sharing the same resident process, close those first.
With the daemon gone, codex login let the newly started TUI itself bind localhost:1455, receive the browser’s OAuth redirect, and complete the sign-in.
A checking order for the same symptom
The problem is often the local state going stale rather than anything on the ChatGPT account, so this order is fast:
- Use
codex login statusand the timestamp on~/.codex/auth.jsonto confirm that credentials have been refreshed - Use
lsof -i :1455to see which process ownslocalhost:1455, and check whether acodex app-server --managed-daemonfrom an earlier session (rather than the TUI you just launched) is listening - Press Esc and relaunch
codexfirst - If that does not clear it, kill the resident process and rerun
codex login. If the Codex desktop app or a browser extension shares the same daemon, close those before killing it - Keep
codex login --device-authas a fallback only when you are willing to change ChatGPT’s device-code security setting
That’s all from tracing the “Finish signing in via your browser” hang in Codex CLI to a stale codex app-server --managed-daemon holding localhost:1455 and resolving it by killing the daemon and rerunning codex login, from the Gemba.