`remote-control pair` times out after 2s while backend pairing request allows 30s
What version of Codex CLI is running?
codex-cli 0.147.0
What subscription do you have?
ChatGPT Plus
Which model were you using?
Not applicable; this occurs before starting a model turn.
What platform is your computer?
Linux 7.0.14-9-pve x86_64 x86_64
Ubuntu 24.04 guest.
What terminal emulator and version are you using (if applicable)?
SSH session; TERM=screen.xterm-256color.
Codex doctor report
Privacy-trimmed to the relevant checks:
{
"schemaVersion": 1,
"overallStatus": "fail",
"codexVersion": "0.147.0",
"checks": {
"app_server.status": {
"status": "ok",
"summary": "background server is running",
"details": {"app-server version": "0.147.0", "mode": "persistent", "status": "running"}
},
"auth.credentials": {
"status": "ok",
"summary": "auth is configured",
"details": {"stored ChatGPT tokens": "true", "stored auth mode": "chatgpt"}
},
"network.env": {
"status": "ok",
"details": {"proxy env vars present": "HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, NO_PROXY, http_proxy, https_proxy, all_proxy, no_proxy"}
},
"network.provider_reachability": {
"status": "fail",
"summary": "one or more required provider endpoints are unreachable over HTTP",
"details": {"ChatGPT base URL": "request timed out (required)"},
"durationMs": 3017
},
"network.websocket_reachability": {
"status": "ok",
"summary": "Responses WebSocket handshake succeeded",
"details": {"handshake result": "HTTP 101 Switching Protocols"},
"durationMs": 5329
},
"installation": {
"status": "ok",
"summary": "installation looks consistent",
"details": {"install context": "standalone", "platform": "linux-x86_64", "version": "0.147.0"}
}
}
}
What issue are you seeing?
codex remote-control start --json succeeds and reports a connected daemon, but codex remote-control pair consistently fails at almost exactly two seconds:
$ time codex remote-control pair
Error: timed out waiting for remoteControl/pairing/start response
Caused by:
deadline has elapsed
real 0m2.023s
user 0m0.001s
sys 0m0.008s
The local app-server receives remoteControl/pairing/start, performs the backend HTTPS request, and completes shortly after the daemon CLI client disconnects. Representative debug trace:
12:40:07.807 remoteControl/pairing/start received
12:40:07.820 connecting to chatgpt.com through HTTP proxy
12:40:09.924 pairing handler completes
12:40:09.924 dropping message for disconnected connection
The handler needed about 2.117 seconds, while the caller stopped waiting after 2 seconds.
A minimal WebSocket-over-UDS diagnostic client using a 15-second response timeout successfully received valid pairingCode and manualPairingCode fields from the same app-server. This confirms that authentication, enrollment, the pairing endpoint, and response parsing work when the local caller waits long enough.
Relevant source:
- generic 2-second control-socket response timeout
- pairing waits using that timeout
- backend pairing request permits 30 seconds
- PR #29913 introduced the daemon pairing command; its unit test returns immediately and does not exercise backend or proxy latency.
Current main still defines CONTROL_SOCKET_RESPONSE_TIMEOUT as two seconds.
What steps can reproduce the bug?
- Authenticate the CLI using ChatGPT.
- Use a functioning HTTP proxy with approximately 2-3 seconds of ChatGPT request latency. The daemon inherits all upper- and lowercase proxy variables.
- Run
RUST_LOG=debug codex remote-control start --json. - Confirm it reports
"status":"connected". - Run
time codex remote-control pair --json. - Observe that it exits after approximately 2.02 seconds.
- Inspect the daemon log and observe that the pairing handler completes later and drops its response because the Unix-socket client disconnected.
This reproduces consistently. Authenticated model-list HTTP requests and Remote Control WebSocket handshakes succeed through the same proxy.
What is the expected behavior?
codex remote-control pair should wait long enough for the pairing backend operation to finish and print the short-lived pairing code.
Pairing should use a dedicated response timeout longer than the backend request timeout rather than the generic two-second control-socket probe timeout. Since the backend allows 30 seconds, a slightly longer caller timeout would also allow backend timeout errors to propagate instead of masking them as a local control-socket timeout.
Additional information
Repeated CLI retries can leave pairing handlers running after each caller disconnects. Because pairing requests are serialized, retries can queue more pairing operations and make later attempts slower.
No exact existing issue was found for the error string, remoteControl/pairing/start, or CONTROL_SOCKET_RESPONSE_TIMEOUT. Related mobile pairing reports exist, but this report is intentionally limited to the independently reproduced CLI timeout.
4 Comments
Follow-up verification: I built a minimal client that performs the same app-server initialization and sends exactly one
remoteControl/pairing/startrequest, but waits up to 35 seconds. A live invocation successfully returned a valid manual pairing code in approximately 2.2 seconds.This is just beyond the stock daemon client's fixed 2-second response timeout and provides an end-to-end confirmation that increasing the pairing-specific timeout resolves the reported failure. No retries were required.
I published the minimal workaround used for the follow-up verification: https://github.com/PRO-2684/codex-pair-long
It connects to the existing Codex app-server Unix control socket, sends exactly one
remoteControl/pairing/startrequest, performs no automatic retries, and waits 35 seconds by default. Installation directly from the public repository and the CLI entry point were verified. It is explicitly documented as an unofficial workaround for the experimental protocol and should be retired in favor of the stock command once this issue is fixed.Confirmed the constant collision on
main(1f41cc5d92):remoteControl/pairing/startwaits for its response behind the genericCONTROL_SOCKET_RESPONSE_TIMEOUT = Duration::from_secs(2)(https://github.com/openai/codex/blob/1f41cc5d92/codex-rs/app-server-daemon/src/client.rs#L25, used inread_remote_control_responseatremote_control_client.rs#L225-L230). That constant is sized for what the socket is usually asked — local probe/version round-trips to a daemon on the same machine — butpairing/startis the one control-socket call whose handler must complete a network round-trip to the ChatGPT backend to mint the pairing session before it can respond. Any backend latency over ~2 s (cold connection, high-RTT region, proxy) fails the CLI while the daemon-side request is still legitimately in flight — matching your consistent 2.02 s failures against a healthy connected daemon.Fix is a per-method deadline: keep 2 s for probe/lifecycle calls and give pairing (and any other backend-proxying method) a budget matching the backend's own allowance — the 30 s you measured — by threading a
Durationparameter throughread_remote_control_responseinstead of the shared constant. One signature change plus two call sites.Confirmed independently on Codex CLI
0.149.1under WSL2.remote-control startconnected successfully, whileremote-control pairfailed at the generic local response deadline with:I implemented the per-operation timeout described above: the pairing request uses a deadline long enough for the backend pairing operation, while ordinary daemon control-socket operations retain the short probe timeout.
Reference commit: https://github.com/cendyandreoli/codex/commit/25163c0032bd784a0cb041fee5ba1911e826bbee
The focused daemon tests pass, and live WSL validation then returned both
pairingCodeandmanualPairingCodesuccessfully. The complete reference branch, including an in-TUI/remote-controlflow, is linked in #38115.