Codex CLI hangs on Ubuntu during normal prompts

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

What version of Codex CLI is running?

0.117.0

What subscription do you have?

Pro

Which model were you using?

gpt 5.3 Codex, gpt 5.4 (fast for both)

Note: I am using 5.4 Pro with extended thinking on the web to solve some tasks, it does feel like when I am running these rather large tasks on the web, it slows down the speed of codex cli, not sure if this is an account throttling issue.

What platform is your computer?

Ubuntu

What terminal emulator and version are you using (if applicable)?

_No response_

What issue are you seeing?

Codex CLI hangs on Ubuntu during normal prompts. Started around March 28–29, 2026. After sending a prompt, Codex remains stuck (thinking/working) for extended periods

What steps can reproduce the bug?

1) launch codex 2) send prompt X 3) observe hang. Version: __. Ubuntu: __.Network: __. Frequency: __%.

What is the expected behavior?

_No response_

Additional information

_No response_

View original on GitHub ↗

3 Comments

github-actions[bot] contributor · 5 months ago

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

  • #16166
  • #15990
  • #15454

Powered by Codex Action

Veridiann · 5 months ago

Codex CLI Hanging / Stalling — Root Cause Analysis & Fix

Date: 2026-03-29
System: Linux 6.17.0-19-generic, Codex CLI v0.117.0
Affected models: gpt-5.4, gpt-5.3-codex, gpt-5.3-codex-spark

---

Symptom

Codex CLI sessions randomly hang for extended periods (5-30+ minutes). The UI
appears stuck on "working" with no output. Log messages show repeated:

stream disconnected - retrying sampling request (N/5 in XXXms)...

Sessions sometimes recover after retries; other times they stall through
multiple retry cycles before completing.

---

Investigation Summary

What was checked

| Check | Result |
|-------------------------------|--------------------------------------|
| Network connectivity (ping) | 3.6ms to OpenAI — excellent |
| HTTPS latency to api.openai.com | ~150ms — consistent and stable |
| Packet loss | 0% |
| Network interface errors | None (0 TX/RX errors) |
| DNS resolution | 4ms — fast |
| System resources | 91GB RAM, 49GB free — no pressure |
| Firewall (iptables) | Default ACCEPT policy — no blocking |
| IPv6 connectivity | Working (15ms to OpenAI via IPv6) |
| OpenAI status page | "All Systems Operational" |
| Connection tracking (conntrack) | 432000s timeout — not the issue |

All network and system health checks passed. The issue is not local
infrastructure.

The real evidence: log analysis

Analysis of ~/.codex/log/codex-tui.log (51,701 lines, 16MB) revealed
87 stream disconnections over a 23-hour period (2026-03-28 14:00 to
2026-03-29 13:02).

Each disconnection is preceded by a websocket close event that logs its
time.idle value — the duration the websocket had zero data flowing before
being terminated. The distribution:

| Idle duration before disconnect | Count | Percentage |
|--------------------------------|-------|------------|
| ~300 seconds (295-360s) | 62 | 71% |
| 5-18 seconds | 14 | 16% |
| Sub-second (<1s) | 11 | 13% |

71% of all disconnections occur after exactly ~300 seconds of idle time.

Example from the log:

12:10:02  websocket opens (new request sent to gpt-5.4)
          ... model is "thinking", no data flows ...
12:15:02  close time.idle=300s     <-- killed after exactly 5 min idle
12:15:02  WARN: stream disconnected - retrying sampling request (1/5 in 215ms)
12:15:03  websocket reopens (retry)
          ... model still thinking ...
12:20:18  close time.idle=302s     <-- killed again after 5 min
12:20:18  WARN: stream disconnected - retrying sampling request (1/5 in 211ms)

This pattern repeats. For long-thinking requests, the retry counter escalates
(1/5 -> 2/5 -> 3/5 -> 4/5) as each retry also times out at 300s.

Models affected

| Model | Disconnects at ~300s |
|--------------------|--------------------|
| gpt-5.4 | 28 |
| gpt-5.3-codex | 24 |
| gpt-5.3-codex-spark| 10 |

---

Root Cause

Primary: Server-side 300-second websocket idle timeout

OpenAI's API infrastructure (likely Cloudflare's reverse proxy) enforces a
300-second idle timeout on websocket connections. When no data frames pass
over the websocket for 300 seconds, the connection is terminated.

This becomes a problem with "thinking" models (gpt-5.4, gpt-5.3-codex) because:

  1. Codex sends a request via websocket
  2. The model enters an extended reasoning/thinking phase
  3. During thinking, zero output tokens are streamed — the websocket is idle
  4. After 300s of silence, the proxy kills the connection
  5. Codex detects the disconnect and retries with exponential backoff
  6. If the model is still thinking, the retry also times out at 300s

Aggravating factor: model_reasoning_effort = "xhigh"

The Codex config had model_reasoning_effort = "xhigh", which instructs the
model to spend maximum time reasoning before responding. This dramatically
increases the probability that thinking time exceeds the 300-second timeout,
because the model is explicitly being told to think as long as it needs.

Why the previous diagnosis (TCP keepalive) was wrong

The previous investigation session diagnosed TCP keepalive settings (7200s) as
the root cause and recommended lowering them. This was incorrect because:

  1. Wrong timescale: TCP keepalive fires at 7200s; disconnections happen at

300s. The two are unrelated.

  1. Wrong OSI layer: TCP keepalive operates at Layer 4 (transport). The 300s

proxy timeout operates at Layer 7 (application). TCP keepalive probes are
invisible to HTTP/websocket proxy timeouts.

  1. Wrong mechanism: Cloudflare's idle timeout counts websocket data frames,

not TCP keepalive probes. Sending TCP keepalive packets would not prevent
the proxy from closing the connection.

TCP keepalive hardening is still good practice (and was applied), but it does
not address this specific issue.

---

Fixes Applied

Fix 1 (Primary): Lower reasoning effort — xhigh -> high

File: ~/.codex/config.toml

- model_reasoning_effort = "xhigh"
+ model_reasoning_effort = "high"

Why this helps: With "high" instead of "xhigh", the model spends less
time in extended reasoning, making it far less likely that the thinking phase
exceeds the 300-second websocket timeout. The quality difference between "high"
and "xhigh" is marginal for most coding tasks — "xhigh" is designed for
extremely complex multi-step reasoning that rarely benefits routine development
work.

To revert: Change back to "xhigh" in ~/.codex/config.toml if you need
maximum reasoning depth for a specific task. Be aware that sessions may stall
on complex prompts.

Fix 2 (Secondary): TCP keepalive hardening

File: /etc/sysctl.d/99-tcp-keepalive.conf

net.ipv4.tcp_keepalive_time = 60    # was 7200 (2 hours)
net.ipv4.tcp_keepalive_intvl = 20   # was 75
net.ipv4.tcp_keepalive_probes = 5   # was 9

Why this was applied: While not the primary fix, lower TCP keepalive values:

  • Detect dead connections faster (160s total vs 11+ minutes previously)
  • May help prevent router NAT table expiration for idle connections
  • Are a reasonable default for any system with long-lived connections

To revert: sudo rm /etc/sysctl.d/99-tcp-keepalive.conf && sudo sysctl -p

---

What would fully fix this (requires OpenAI)

The definitive fix is for the Codex CLI to send websocket ping frames at a
regular interval (e.g., every 30-60 seconds) during active requests. This would
reset the proxy's idle timer and keep the connection alive regardless of how long
the model thinks.

This is a known pattern for websocket applications behind reverse proxies. Until
OpenAI implements this in the Codex CLI, the reasoning effort reduction is the
best user-side mitigation.

Consider filing an issue at: https://github.com/openai/codex/issues

---

Monitoring

To check if disconnections are still occurring after the fix:

# Count disconnections since the fix was applied (after 13:02 UTC on 2026-03-29)
grep "stream disconnected" ~/.codex/log/codex-tui.log | \
  awk -F'T' '$1 >= "2026-03-29" && $2 >= "13:02"' | wc -l

# Check idle durations of any new disconnections
grep -B1 "stream disconnected" ~/.codex/log/codex-tui.log | \
  grep "time.idle" | grep -oP 'time\.idle=\K[0-9.]+[a-zµ]+'

# Watch the log in real-time for disconnections
tail -f ~/.codex/log/codex-tui.log | grep "stream disconnected"

If disconnections at ~300s persist even with "high" effort, consider lowering
to "medium" for routine tasks and only using "high" for complex work.

---

Timeline of disconnection events

Mar 28 14:00 - 15:50  |  30 disconnections  |  Heavy usage, multiple sessions
Mar 28 17:50 - 18:57  |   3 disconnections  |  Sporadic
Mar 28 19:14 - 23:53  |   5 disconnections  |  Low frequency (~1/hour)
Mar 29 00:53 - 08:24  |   2 disconnections  |  Overnight, minimal usage
Mar 29 09:17 - 09:43  |  13 disconnections  |  Burst: 3 concurrent sessions
Mar 29 10:14 - 11:01  |   7 disconnections  |  Active session with retries
Mar 29 11:30 - 12:51  |  17 disconnections  |  Peak: model thinking > 25 min
Mar 29 12:57 - 13:02  |  10 disconnections  |  (investigation session)

Total: 87 disconnections in 23 hours.

aborruso · 4 months ago

Confirming this bug on WSL2 (Ubuntu on Windows 11, codex v0.118.0).

Symptoms:

  • Both codex (TUI) and codex exec hang indefinitely
  • Ctrl+C does not interrupt; process must be killed
  • Happens with all models tested: gpt-5.4, gpt-4o, o4-mini, codex-mini-latest
  • codex --help and codex exec --help work fine
  • OpenAI API key is valid (curl to api.openai.com returns 200)
  • Status: logged in with ChatGPT

Root cause (from RUST_LOG=debug):

The process always hangs at plugin startup sync with chatgpt.com:

DEBUG hyper_util::client::legacy::connect::http: connecting to 172.64.155.209:443
DEBUG hyper_util::client::legacy::connect::http: connected to 172.64.155.209:443
DEBUG opentelemetry_sdk: name="Metrics.InstrumentCreated" instrument_name="codex.plugins.startup_sync"
DEBUG opentelemetry_sdk: name="Metrics.InstrumentCreated" instrument_name="codex.plugins.startup_sync.final"
[hangs here indefinitely]

The HTTP connection to chatgpt.com succeeds (no Cloudflare block, no 403), but the startup_sync WebSocket/long-poll never completes under WSL2.

Workarounds attempted (none worked): disabling MCP servers via -c 'mcp_servers={}', disabling plugins, switching models, --dangerously-bypass-approvals-and-sandbox.