Codex keep reconnecting

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

Date:6.15 19:12 China mainland
Codex is keep reconnecting and it takes really long time and still didn't do any work. Sometimes, it will reply something first then start reconnecting again. I don't know if it's a bug of codex or my internet problem. I hope that someone can tell me the solution soon, it really distracted the progress of my project.

<img width="720" height="185" alt="Image" src="https://github.com/user-attachments/assets/25244d41-09cd-4e86-8f47-19bca0d8a975" />

View original on GitHub ↗

5 Comments

github-actions[bot] contributor · 2 months ago

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

  • #27625
  • #26720
  • #26696
  • #27661
  • #27952

Powered by Codex Action

tolgaergin · 2 months ago

It's duplicated issue for a long time and it's not fixed.

I'm seeing frequent stream disconnected before completion: idle timeout waiting for websocket errors in Codex App and VS Code.

This is not related to repo size, model, or reasoning effort. I've reproduced it with GPT-5.5 Low, High, and XHigh, and even on very simple prompts. The behavior appears random.

Typical pattern:

Task starts normally.
After ~5 minutes: Reconnecting 1/5
Repeats through Reconnecting 5/5
During reconnects the agent sometimes continues making progress (reading/editing files).
After the final reconnect the task often resumes normally.

<img width="767" height="556" alt="Image" src="https://github.com/user-attachments/assets/c656764f-0188-4de1-95a7-cb46f94cbb62" />

This feels more like a websocket/streaming/agent transport issue than a model-quality or repo-size issue. Several users appear to be reporting similar idle timeout waiting for websocket reconnect loops.

After 5/5 everything turns to normal for couple of minutes then it starts 1/5 2/5 3/5 4/5 5/5.

Codex app, vscode, cli not usable anymore

xsourabhsharma · 2 months ago

are you on window? check node_repl.exe if this is broken then it caused "timeout waiting for child process to exit"

tolgaergin · 2 months ago

Thanks. I'm on macOS, not Windows.

Codex App version: 26.609.41114
codex-cli: 0.139.0
No proxy, VPN, or MDM

The behavior is random. Sometimes Codex works perfectly, sometimes a simple task ends up taking 20–40 minutes because it cycles through Reconnecting 1/5 → 2/5 → 3/5 → 4/5 → 5/5

tolgaergin · 2 months ago

TL;DR - this is Cloudflare's ~100 s idle-WebSocket timeout, not your network.

Codex's default Responses transport is a WebSocket, and chatgpt.com is served through Cloudflare, which closes any WebSocket with no frames in either direction for ~100 s. On a long turn the model can stay silent past 100 s → Cloudflare drops the socket → idle timeout waiting for websocket → Reconnecting 1/N. It's noticeably worse with high model_reasoning_effort, because the silent gaps between tokens are longer.

Workaround that fixes it today force the HTTP/SSE transport (SSE is a normal HTTP stream, so the 100 s WebSocket cap never applies). Add to ~/.codex/config.toml and fully restart Codex:

because it changes model_provider the previous conversations will not be visible after you uedit config.toml file and restart the codex app - I asked handoff prompt from the conversation that i want to continue.

model_provider = "chatgpt-http"

# Force SSE instead of WebSocket so Cloudflare's 100s idle-WS timeout can't drop long turns
[model_providers.chatgpt-http]
name = "ChatGPT (HTTP/SSE)"
base_url = "https://chatgpt.com/backend-api/codex"
wire_api = "responses"
requires_openai_auth = true
supports_websockets = false

Root cause (confirmed in the codebase): the Responses WebSocket transport never sends client-initiated keepalive pings.

In codex-rs/codex-api/src/endpoint/responses_websocket.rs, the WsStream pump task drives the socket with a tokio::select! that has only two arms, outgoing commands, and inner.next() for incoming frames. The incoming path answers a server Ping with a Pong but never initiates a ping, and there is no timer arm. tokio-tungstenite doesn't auto-ping, so during a long, quiet reasoning turn (no Text frames from the server, no client commands) the socket sits fully idle.

chatgpt.com is fronted by Cloudflare, whose default idle-WebSocket timeout is 100 s (Free/Pro, not configurable below Enterprise). A quiet turn past ~100 s is closed by the edge and surfaces as idle timeout waiting for websocket → Reconnecting N/5. It's worse at higher model_reasoning_effort since the silent gaps are longer. Almost certainly the same root cause as #27625, #24533, #18960, #20739.

I ruled out the local network from the affected machine: a control idle TLS connection to an unrelated host held 10 minutes untouched, and idle-close times varied per-CDN (i.e. server-side, not a local middlebox). So this is the edge in front of the Responses API, not users' networks.

Fix outline - add a keepalive arm to the pump loop: a tokio::time::interval (~30 s, well under 100 s) that sends Message::Ping. The pump owns the sink and keeps running while the cached connection is idle between/within turns, so it keeps exactly the gaps that currently die warm. Mirrors the existing keepalive in app-server-transport/.../remote_control/websocket.rs.

// inside the pump task in WsStream::new
let mut keepalive =
    tokio::time::interval_at(Instant::now() + KEEPALIVE, KEEPALIVE);
keepalive.set_missed_tick_behavior(MissedTickBehavior::Skip);
// ...and a third select! arm:
_ = keepalive.tick() => {
    if let Err(err) = inner.send(Message::Ping(Vec::new().into())).await {
        let _ = tx_message.send(Err(err));
        break;
    }
}

I've implemented this with a passing unit test (a loopback WS server asserting the pump emits a client-initiated ping). I see external contributions are invitation-only, happy to open a PR if the team would like it; https://github.com/tolgaergin/codex/commit/320a3c0