Responses WebSocket stalls 300s per retry; opt-out flag removed; HTTPS fallback requires 5 failed retries

Open 💬 4 comments Opened Aug 14, 2026 by etcendureanalytics
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Environment: ChatGPT desktop 26.810.41047 (macOS, Darwin 25.3.0), bundled codex-cli 0.148.0-alpha.9, model gpt-5.6-sol (high/max reasoning effort), service_tier priority, ChatGPT-plan auth.

Symptom: Sampling over wss://chatgpt.com/backend-api/codex/responses goes silent mid-turn. The client detects the dead stream only via a 300s idle timeout (codex_core::responses_retry: stream disconnected before completion: idle timeout waiting for websocket; sometimes IO error: Connection reset by peer (os error 54)). Each retry cycle is a ~5-minute user-visible stall with frozen token counts.

Evidence (2026-08-14, UTC):

  • Thread 01a00079-2445-7f01-a7a1-2764c376afe9: 11 stalls of 301–310s between 13:33–14:35, including four consecutive (13:59 → 14:15).
  • Turn 01a00191-22f6-79f1-a260-71201ed53982: exhausted retries 5/5 at 19:17.
  • A prior incident produced 16 five-minute reconnects across three tasks in one day.

Aggravating factors:

  1. responses_websockets / responses_websockets_v2 are stage removed in codex features list — users cannot opt out of the websocket transport.
  2. Built-in provider override is rejected ("model_providers contains reserved built-in provider IDs"), so supports_websockets / stream_idle_timeout_ms are unreachable.
  3. HTTPS fallback only engages after 5 failed retries (~25 minutes of stalling).

The network here has documented upstream packet loss under load, which is presumably the trigger — but SSE-based clients on the same link detect drops and recover in seconds. The websocket transport takes 300s per detection with no user recourse.

Request: websocket-level keepalive/liveness so a dead stream is detected in seconds rather than 300s; and/or restore the transport opt-out; and/or engage the HTTPS fallback on the first idle timeout instead of the fifth.

Related: #27625, #28579

View original on GitHub ↗

4 Comments

github-actions[bot] contributor · 13 days ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #37957
  • #37660
  • #37649
  • #37894

Powered by Codex Action

etcendureanalytics · 9 days ago

Follow-up with stronger evidence that this is transport/server-side, not the local network.

2026-08-18 (ChatGPT desktop 26.810.52044, same bundled codex-cli 0.148.0-alpha.9): 33 websocket idle-timeout stall/retry cycles logged in one day — worst so far. Example chain: turn 01a0162c-a4d2-71e2-80f1-dab3f385118c hit retries 1→4 at 18:47:06, 18:52:11, 18:57:19, 19:02:28 UTC (one ~5-minute frozen stall per retry), preceded by turn 01a015fa-40b7-7780-b354-99e3e29fcb1b retries at 18:31:44 / 18:36:51. All stream disconnected before completion: idle timeout waiting for websocket.

The key datapoint: an automated hourly line-quality test ran at 18:32 UTC — in the middle of that stall cluster — and measured 22 Mbps up / 360 Mbps down with zero errors and 0% idle packet loss to the ISP's first hop. The local link was verifiably healthy at the exact minutes the websocket streams were stalling. (This host previously had a genuinely lossy uplink; on 2026-08-18 it tested clean all day — 14/14 hourly runs passed — while Codex logged its worst stall count yet.)

This rules out the local-network explanation for these episodes and points at the websocket path (edge terminates at DFW per cf-ray) or upstream sampling. The 300s detection time and 5-retries-before-HTTPS-fallback turn each server-side hiccup into 5–25 minutes of frozen UI.

Re-requesting: ws keepalive/liveness (seconds, not 300s), transport opt-out, or first-timeout HTTPS fallback.

aygerix · 7 days ago

Related but not the same failure mode: #39771.

We hit the same idle timeout waiting for websocket + silent retrying sampling request (n/5) on Desktop 26.814.41407 / 0.148.0-alpha.15 / gpt-5.6-sol high.

A localhost reverse proxy injecting unknown-type text frames ({"type":"codex.client.keepalive"}) every 45s stopped the idle timeout. Codex logged unhandled responses event: "codex.client.keepalive" and the same in-flight request resumed with a real tool/patch after ~8.5 min of no model text.

So at least some of these 300s stalls are false dead-streams (no Responses text during high-reasoning), not packet loss. Faster dead-stream detection would have aborted a live turn. Built-in openai still cannot set stream_idle_timeout_ms / supports_websockets, which matches this issue.

KoljaB · 4 days ago

Additional sanitized prevalence data from Codex Desktop 26.818.41509 / bundled command runner 0.149.0-alpha.4.1:

A seven-day local host audit found 296 Responses WebSocket retry log entries across 175 tasks. I cannot determine billing impact from local logs and am not asserting that every retry was charged. The important operational result is that reconnect/fallback is common enough to amplify latency and agent recovery work.

This supports a session-level circuit breaker or supported transport selector: after a confirmed transport failure, switch once to HTTPS rather than repeating the same WebSocket path through the full retry budget.