Windows + Android Remote Control enters reconnect loop after successful initialize/thread-list
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Summary
Codex Remote Control on Windows is currently unusable from Android.
The issue initially appeared as:
409 Conflict
{"detail":"Remote app server already online"}
That stale-server condition has since been cleared. The Windows app-server now connects successfully to the Remote Control websocket and reports Connected, but Android still cannot establish a usable Remote session.
Versions
- Codex Desktop: 26.818.31338
- Bundled app-server: 0.149.0-alpha.4
- ChatGPT Android: 1.2026.223 (20)
- Android 16
- Windows 11 desktop host
Current behavior
On clean startup, Remote Control looks healthy:
remoteControl/status/read ... errorCode=null
remote control websocket status changed ... next_status=Connected
connected to app-server remote control websocket
remoteControl/enable ... errorCode=null
The original 409 is no longer present.
During an Android connection attempt at:
2026-08-21 14:45:07 UTC
the Windows app-server receives:
initialize connection_id=ConnectionId(2) request_id=Integer(10)
thread/list connection_id=ConnectionId(2) request_id=Integer(11)
initialize was received at approximately 14:45:07.080Z and thread/list at 14:45:07.673Z, about 593 ms later.
No local error or connection closed event is logged for ConnectionId(2).
After that, new remote connections are opened. ConnectionId(3) through ConnectionId(9) are created and then immediately closed:
initialize ConnectionId(3)
forwarding remote control connection closed ... ConnectionId(3)
and in some cases:
forwarding remote control connection closed ... ConnectionId(4)
initialize ConnectionId(4)
dropping message for disconnected connection: ConnectionId(4)
dropping message for disconnected connection: ConnectionId(4)
The same pattern repeats for later connection IDs.
On Android, the PC is discovered and shown as connecting/reconnecting, but the session never becomes usable.
Historical comparison
The same logs_2.sqlite contains older healthy Remote sessions where the flow continues normally:
initialize ConnectionId(3)
thread/list ConnectionId(3)
...
connection closed ConnectionId(3)
Other historical sessions also reach:
initialize ConnectionId(4)
thread/list ConnectionId(4)
This shows that the Android client and the app-server are capable of completing the handshake and progressing beyond initialize.
Troubleshooting already performed - Full Desktop restart
- Reinstalled Codex Desktop from Microsoft Store
- Revoked and re-paired Android
- Cleared Android cache and full app storage
- Signed in again and re-paired
- Backed up Codex state
- Cleared remote_control_enrollments
- Removed persisted Remote Control environment/installation keys from global state
- Rotated the main Codex installation_id
- Confirmed the new installation identity differs from the previous one
- Fixed an accidental UTF-8 BOM in .codex-global-state.json and its backup
- Confirmed clean startup loads global state normally
- Confirmed Remote websocket is currently Connected
- Confirmed the original 409 is gone
The problem still reproduces with the fresh installation identity.
Expected behavior
After Android sends:
initialize
thread/list
the Remote session should remain usable and display the host's conversations.
Actual behavior
One connection reaches:
initialize -> thread/list
but never becomes usable on Android.
After that, new remote connections are repeatedly opened and immediately closed during initialize.
Suspected area
This looks like a Remote Control session/relay lifecycle desynchronization rather than a basic pairing, firewall, local enrollment, or host websocket problem.
It appears possible that one side still considers the first Remote connection alive while another part of the Remote Control path starts opening replacement connections.
Related issue - #28862 — stale Remote enrollment / 409 Remote app server already online
I can provide sanitized excerpts from logs_2.sqlite with exact timestamps if needed. Account IDs, installation IDs, server IDs and environment IDs are intentionally omitted.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the remoteControl/status/read and remoteControl/enable events, then trace the initialize and thread/list sequence for ConnectionId(2) against later connections in logs_2.sqlite. Compare it with the historical healthy sessions and determine why replacement connections close immediately. Done means Android establishes a usable session, displays the host's conversations, and no longer enters the reconnect loop.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, desktop, mobile, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100