Codex mobile pairing stuck on Waiting for desktop when remote-control daemon cannot use proxy
What version of the Codex App are you using (From “About Codex” dialog)?
Codex Desktop 26.513.20950, build 2816 (com.openai.codex)
Bundled CLI/app-server:
/Applications/Codex.app/Contents/Resources/codex --version
codex-cli 0.131.0-alpha.9
What subscription do you have?
ChatGPT account signed into Codex Desktop and ChatGPT mobile app. Same account/workspace on both sides.
What platform is your computer?
macOS, Apple Silicon / arm64. The backend-reported remote-control environment OS was Mac OS 26.3.0, arch arm64.
The machine uses a local network proxy:
HTTP proxy: 127.0.0.1:7897
HTTPS proxy: 127.0.0.1:7897
SOCKS proxy: 127.0.0.1:7897
What issue are you seeing?
Codex mobile pairing gets stuck after scanning the QR code:
- Android/iOS ChatGPT opens the Codex pairing flow but stays on
Waiting for desktop. - Codex Desktop stays on the QR /
Approve on your devicescreen. - No visible desktop approval prompt appears.
- Re-scanning fresh iOS and Android QR codes did not help.
After debugging locally, this appears to be because the headless remote-control daemon was not using the machine's proxy configuration, so it could not report the local Mac as an online remote-control environment to the backend. The desktop UI could still show the QR code, which made this look like a pairing/mobile problem, but the backend environment list stayed empty.
What steps can reproduce the bug?
- On macOS with a required local proxy, open Codex Desktop.
- Open Settings → Set up Codex Mobile / Control this Mac and generate a QR code.
- Scan from ChatGPT mobile app on Android or iOS.
- Observe the phone remains on
Waiting for desktopand the desktop QR page does not progress.
Diagnostics from the failing state
The local remote-control daemon was running and claimed remote control was enabled:
$ /Applications/Codex.app/Contents/Resources/codex remote-control
{"status":"alreadyRunning","backend":"pid","socketPath":"/Users/.../.codex/app-server-control/app-server-control.sock","cliVersion":"0.131.0-alpha.9","appServerVersion":"0.131.0-alpha.9"}
The socket and process existed:
~/.codex/app-server-control/app-server-control.sock
~/.codex/packages/standalone/current/codex -> /Applications/Codex.app/Contents/Resources/codex
But the backend API returned no remote-control environments for the account:
GET https://chatgpt.com/backend-api/codex/remote/control/environments?limit=100
{"items":[],"cursor":null}
Local SQLite also did not change after scanning; existing remote_control_enrollments rows were old and no new row was added.
The smoking gun was lsof on the remote-control daemon. Before the workaround, it was trying to connect directly to an external HTTPS address and remained stuck in SYN_SENT:
codex <pid> ... TCP <local-ip>:<port>-><external-ip>:https (SYN_SENT)
Direct backend access from this machine also timed out without the proxy, while the same request succeeded with --proxy http://127.0.0.1:7897.
Workaround that made the backend see the Mac
Restart only the remote-control daemon with explicit proxy environment variables:
pkill -f '/Users/.*/.codex/packages/standalone/current/codex .*remote_control app-server --listen unix://' 2>/dev/null || true
pkill -f '/Users/.*/.codex/packages/standalone/current/codex app-server daemon pid-update-loop' 2>/dev/null || true
HTTP_PROXY=http://127.0.0.1:7897 \
HTTPS_PROXY=http://127.0.0.1:7897 \
ALL_PROXY=http://127.0.0.1:7897 \
http_proxy=http://127.0.0.1:7897 \
https_proxy=http://127.0.0.1:7897 \
all_proxy=http://127.0.0.1:7897 \
NO_PROXY=localhost,127.0.0.1,::1 \
no_proxy=localhost,127.0.0.1,::1 \
/Applications/Codex.app/Contents/Resources/codex remote-control
After this, lsof showed the daemon using the local proxy:
codex <pid> ... TCP localhost:<port>->localhost:7897 (ESTABLISHED)
And the backend environment list immediately changed from empty to one online Mac:
{
"items": [
{
"kind": "single",
"display_name": "<hostname>.local",
"online": true,
"busy": false,
"os": "Mac OS",
"arch": "arm64",
"app_server_version": "0.131.0-alpha.9",
"client_type": "CODEX_DESKTOP_APP",
"originator": "Codex Desktop"
}
],
"cursor": null
}
Expected behavior
The remote-control daemon should either:
- inherit/use the macOS system proxy configuration used by the Codex Desktop/Electron network layer, or
- inherit proxy environment variables from the desktop app, or
- surface a clear error in the QR pairing UI when it cannot reach the remote-control backend.
Actual behavior
The UI silently remains in the QR / waiting state, while the daemon cannot reach the backend and the backend has no online desktop environment to pair with. This makes the mobile app appear stuck even though the local daemon and QR UI are both present.
Related issues
This looks related to the broader Waiting for desktop reports, but with a more specific root cause/workaround:
- #22714
- #22715
- #22733
Additional notes
One confusing detail during debugging: the GUI/local app-server appears to remove remote_control = true from ~/.codex/config.toml for the normal local app-server path, while the dedicated remote-control daemon is started with --enable remote_control. That config rewrite does not seem to be the root cause here. The decisive change was whether the remote-control daemon could reach the backend through the proxy.
12 Comments
Additional debugging narrative / how we narrowed this down:
The original symptom looked exactly like a pairing/mobile problem: after scanning the Codex Desktop QR code from ChatGPT mobile, the phone stayed on
Waiting for desktop, while the desktop stayed on the QR / approval screen. This reproduced with both iOS and Android QR flows, and reopening the QR modal did not change the behavior.We first checked the common failure modes reported by other users:
account mismatch/remote_control_client_enrollment_start_account_mismatchpattern seen in some other issues.Waiting for desktop.codex remote-controlcould not find the expected standalone~/.codex/packages/standalone/current/codexbinary.codex remote-controlstart successfully.codex remote-controlreportedremoteControlEnabled: true, and the app-server control socket existed.~/.codex/state_5.sqlite, especiallyremote_control_enrollments.codex features listsometimes showedremote_controlasfalsefor the normal local app-server path.remote_controlfrom the regular config path before local app-server startup, while the dedicated daemon is launched with--enable remote_control.The turning point was comparing local daemon state with backend state.
Even though the local daemon was running:
and the socket existed:
the backend still returned no environments for the account:
That meant the phone was waiting for a desktop environment that the server did not know was online.
The key evidence came from
lsofon the remote-control daemon. In the failing state, the daemon had an outbound HTTPS connection stuck inSYN_SENTto an external address. On this machine, direct access to the backend times out unless traffic goes through the local proxy (127.0.0.1:7897). A manual backend request withcurl --proxy http://127.0.0.1:7897worked, while direct access did not.After restarting only the remote-control daemon with explicit proxy environment variables, the connection changed from direct
SYN_SENTto:Immediately after that, the backend environment list changed from empty to an online Mac:
So the final conclusion is: the visible mobile symptom (
Waiting for desktop) was downstream of the desktop remote-control daemon not being able to reach the remote-control backend. The QR flow and local daemon could appear present, but because the daemon was not using the required proxy, the backend environment list stayed empty and mobile had nothing to connect to.The practical workaround was to start the remote-control daemon with explicit proxy variables. The product-side fix should probably ensure the remote-control daemon inherits or reads the same proxy configuration as Codex Desktop/Electron, and the UI should surface a clear backend connectivity error instead of silently leaving both sides waiting.
I hit what looks like a second failure mode while applying the proxy workaround.
After setting the proxy,
lsofshowed Codex traffic going through the local proxy:However, mobile pairing still stayed on
Waiting for desktop.Further debugging showed that
codex remote-controlwas failing with:On this machine, the expected managed standalone path did not exist at all:
Creating that path and symlinking it to the bundled Codex binary fixed this part:
After that,
codex remote-controlsuccessfully bootstrapped:I then restarted remote-control with explicit proxy environment variables:
Before the explicit proxy restart, local logs showed that a new remote-control enrollment was created, but the WebSocket connection still timed out:
After both fixes, mobile pairing succeeded.
So in this case there were two required fixes:
~/.codex/packages/standalone/current/codexAdditional data point: I am now seeing a stale-host / missing-current-host variant of this issue.
Goal: connect ChatGPT mobile / Codex mobile to my main Mac mini. Instead, mobile keeps showing an old MacBook Pro host. Reinstalling the Android app does not remove it, and I cannot find any mobile-side UI to remove the stale host or add another desktop.
Current server-side environment list for the account only returns the stale MacBook Pro:
The intended host is the Mac mini:
Local state on the Mac mini looks enabled, but it still does not appear in the backend environment list:
Process is running with remote control enabled:
The managed standalone path was also restored on this machine:
But
~/.codex/state_5.sqlitehas no rows inremote_control_enrollments, and the backend environment query still returns only the stale offline MacBook Pro.This appears to be two product issues combined:
/backend-api/codex/remote/control/environments.Request: please provide a way to purge/reset stale remote-control hosts for the account/workspace, or expose a mobile/desktop UI to remove old hosts and force-register the current host.
Having the same issue
sameissue, but quick solutions from me right now, after update codex desktop, I did logout and completely close the app (both on my macOS and iPhone)
Then trying to scan and check on the manage connect from desktop app if the connection success. After that, all worked fine for me
This report is useful because it shows the desktop QR screen can be a false positive.
Generating a QR code only proves the local UI can start the pairing flow. It does not prove the remote-control daemon has successfully registered an online host with the backend.
For debugging, I would split the setup into visible gates:
If gate 1 is green but gate 3 or 4 is red, mobile will sit on
Waiting for desktopeven though the QR path looked valid. The product should probably surface this asdesktop daemon not online / cannot reach backendrather than a generic pairing wait.I've been stuck with the same issue for a week. Thanks OP.
Same issue here.
Codex Mobile Pairing Stuck on "Waiting for Desktop"
I hit the same issue and fixed it. In my case, the QR code was valid, but the desktop host never became an online remote-control environment.
Symptoms
Root Cause
The Codex Desktop app itself may use the macOS proxy, but the managed
remote-control/app-serverdaemon may not inherit the proxy environment variables.As a result, the OpenAI backend never sees the Mac as an online Codex remote-control environment. The QR flow starts, but there is no registered desktop host for the phone to connect to.
Fix
First confirm your local proxy port:
In my case, the proxy was:
Then restart the managed remote-control daemon with explicit proxy environment variables:
If successful, it should print something like:
You can verify that the daemon is really using the proxy:
Expected result:
Also check that there are no direct failed connections:
In the working state, the managed daemon had:
and no Codex
SYN_SENTconnections.Final Step
After the daemon is connected:
Set up Codex mobileagain.The important detail for me was running:
with explicit proxy environment variables. Simply opening the Codex Desktop app or running the command without
startdid not actually bring the managed remote-control daemon online.In my case, I just let my codex desktop app know what the issue look like and post this github issue in it, it helped me yo solve the problem. Now it works!
Confirmed on Windows 11 — same root cause, and here is a Windows workaround that makes the fix persistent.
Environment
OpenAI.Codex_26.623.13972.0_x64)http://127.0.0.1:10808(system proxy is set and the main Codex chat works fine through it)Symptoms (identical to OP)
netstatshows connections stuck inSYN_SENT(the remote-control daemon is trying to reachchatgpt.comdirectly, ignoring the system proxy)Windows workaround (persistent, no manual daemon launch needed)
Instead of launching the daemon manually with env vars (macOS workaround above), set user-level environment variables so the Codex app — and the daemon it spawns — inherit them automatically on every launch:
Then fully kill all Codex processes (closing the window is not enough — check with
Get-Process | Where-Object {$_.ProcessName -match "codex"}) and relaunch the app:After relaunch:
Notes
10808with your own local proxy port.NO_PROXYmatters — without it, local loopback traffic may also be routed to the proxy.[Environment]::SetEnvironmentVariable("HTTP_PROXY", $null, "User")(same for the other two) if needed.Hope the daemon can respect the OS system proxy (or at least the app's own proxy settings) in a future release. 🙏
Hitting the same class of issue on macOS. Sharing diagnosis details in case it helps.
Environment
26.623.101652(build4674), bundled CLIcodex-cli 0.142.5127.0.0.1:7890); the macOS system proxy is properly configured. On this network,chatgpt.comis not reachable via direct connections.Symptom
Reproducible on macOS as well: Settings → Allow devices to control this computer → clicking Allow fails with "Couldn't enable remote control. Try again". Everything else (conversations, etc.) works fine.
Diagnosis: two network paths inside the same process behave differently w.r.t. proxy
Failure in the app logs (
~/Library/Logs/com.openai.codex/...):Running
lsofagainst thecodex app-serverprocess shows both kinds of connections simultaneously:So the main API client honors the macOS system proxy (which is why chat works), while the remote-control path uses a different network client that ignores the system proxy and attempts a direct connection — hence only this feature breaks. This looks like the same root cause as #29958 (on Windows, the WebSocket transport bypasses the system proxy and only honors env vars).
Workaround
Launching Codex with proxy environment variables fully restores remote control (
remoteControl/pairing/startandclient/listboth succeed;lsofconfirms all connections go through the proxy):Since Finder/Dock launches don't inherit shell env vars (see #30695), I keep a minimal wrapper
.appin the Dock (a shell script that exports the proxy vars andexecs the real binary).Expectation: unify proxy behavior between the remote-control path and the main API client — honor the system proxy.