Codex "stream disconnected before completion": What It Means and How to Fix It#
Published by Alex Sorokoletov
"stream disconnected before completion" means the model response stopped before Codex received its final response.completed event. Codex retries the turn 5 times first, so you see the error only when all retries failed. The text after the colon names the cause. For a custom provider, raise stream_max_retries and stream_idle_timeout_ms in config.toml.
What the text after the colon means#
Codex puts the reason after the colon: either a network failure on your side or the error message the server sent. The first group below is network and proxy trouble, and more retries or a longer timeout can help. The last rows are server answers that retrying does not fix.
| Text after "stream disconnected before completion:" | What happened | What to do |
|---|---|---|
stream closed before response.completed | The server or a proxy closed the stream before the last event. | Retry. If it repeats, check the proxy or VPN between you and the provider. |
idle timeout waiting for SSE or idle timeout waiting for websocket | No event arrived for 300,000 ms (5 minutes), the default stream_idle_timeout_ms. | For a slow custom provider, raise stream_idle_timeout_ms. |
Transport error: network error: error decoding response body | The connection broke while Codex was reading the response. | Check the network path: VPN, corporate proxy, unstable Wi-Fi. |
error sending request for url | The request did not get through to the server. | Check DNS, proxy settings and base_url. |
connection refused (os error 61) | Nothing listens at the address (macOS error 61). Common with a local proxy or model server that is not running. | Start the local server, or fix base_url. In v0.166.0 a refused connection makes Codex wait for the network instead (step 4 below). |
failed to send websocket request: io error: … (os error 10054) or (os error 10053) | Windows reset (10054) or aborted (10053) the WebSocket connection, often a VPN, firewall or antivirus. | Allow the connection, or let Codex fall back to HTTPS (it does this after the retries). |
response.failed event received | The server sent a failure event with no error details. | Retry. Codex already did 5 times. |
upstream request failed, bad gateway, upstream service temporarily unavailable, an error occurred while processing your request… | The server or a gateway failed and sent this message. | Wait and retry. Check status.openai.com, or your gateway's logs. |
Incomplete response returned, reason: content_filter | The provider's content filter stopped the response. | Codex adds guidance for the model and retries. Rephrase if it repeats. |
you have no credits remaining… | The account behind the API key has no credits. | Add credits. Retrying does not help. |
could not find an existing deployment to match the model… | Azure has no deployment with the name in model. | Set model to your Azure deployment name. |
What Codex does before it shows the error#
The message is the last step of a retry sequence. In v0.166.0:
- Stream retries. A dropped stream retries the turn up to
stream_max_retriestimes, 5 by default. The wait starts at 200 ms and doubles on each attempt (200, 400, 800, 1,600, 3,200 ms, with up to 10% jitter), unless the server sends a retry-after time.[1] - The notice. Each retry shows
Reconnecting... 2/5. On the WebSocket transport, the first retry is not shown. - HTTPS fallback. When the retries run out on a WebSocket connection, Codex shows "Falling back from WebSockets to HTTPS transport." and starts the retry count again over HTTPS.
- No connection at all. When Codex cannot connect, it waits for the network with no retry limit: "Reconnecting... waiting for network", 5 seconds first, doubling to at most 60 seconds. This does not apply to Amazon Bedrock or to internal sessions.
- The error. Only after these steps does Codex show "stream disconnected before completion" and end the turn.
Before a stream starts, a failed HTTP request is retried separately, up to request_max_retries times (4 by default) on 5xx responses and network errors. A 429 is not retried at that level.
"Error running remote compact task: stream disconnected before completion"#
The prefix means the error happened during compaction, not during a normal turn. With the built-in OpenAI provider and with Azure, Codex compacts a long conversation on the server ("remote compaction"). When that request fails, Codex puts Error running remote compact task: in front of the reason. The rest of the message reads the same as in the table above.
Remote compaction retries at most 2 times, even if stream_max_retries is higher. If compaction fails before a turn, Codex keeps the message you just sent, so you can send it again without retyping.
A related message, "Error running remote compact task: Codex ran out of room in the model's context window. Start a new thread or clear earlier history before retrying.", is not a network error. The conversation is larger than the model's context window, and Codex does not retry it. Start a new thread, or clear history with /clear.
For a custom Responses provider that fails on remote compaction, capabilities.remote_compaction = "unsupported" makes Codex compact locally instead. Custom providers can set it since v0.162.0.
How to change retries and timeouts#
The three keys go in a [model_providers.<id>] table in ~/.codex/config.toml. They apply to that provider only:
model_provider = "azure"
[model_providers.azure]
name = "Azure"
base_url = "https://YOUR_RESOURCE.openai.azure.com/openai/v1"
env_key = "AZURE_OPENAI_API_KEY"
wire_api = "responses"
stream_max_retries = 10
stream_idle_timeout_ms = 600000
request_max_retries = 6
You cannot set them for the built-in openai provider, which is the one you use with "Sign in with ChatGPT" or an OpenAI API key. A [model_providers.openai] table with these keys fails to load with "model_providers contains reserved built-in provider IDs: openai. Built-in providers cannot be overridden." On the built-in provider, the defaults below apply.[2]
| Key | Default | Limit | What it controls |
|---|---|---|---|
stream_max_retries | 5 | 100 | Retries of a turn after a dropped stream |
stream_idle_timeout_ms | 300,000 (5 minutes) | none | Time with no stream event before Codex treats the connection as lost |
request_max_retries | 4 | 100 | Retries of the HTTP request on 5xx and network errors |
| Remote compaction retries | 2 | fixed | The lower of 2 and stream_max_retries |
A value above the limit is lowered to the limit. All three keys are in the Codex config.toml reference.
Timeline#
| Version | Published | Change |
|---|---|---|
| v0.8.0 | 2025-07-19 | stream_max_retries, stream_idle_timeout_ms (default 300,000) and request_max_retries (default 4) replace the OPENAI_* environment variables as per-provider config.toml keys. The stream default is 10. |
| v0.17.0 | 2025-08-07 (tag) | Default stream_max_retries goes from 10 to 5, and the backoff factor from 1.3 to 2. |
| v0.24.0 | 2025-08-26 | Both retry keys are capped at 100. |
| v0.51.0 | 2025-10-30 (tag) | The retry notice reads Reconnecting... 1/5 (before: Re-connecting...). |
| v0.80.0 | 2026-01-09 | First release with the "Error running remote compact task" prefix. |
| v0.93.0 | 2026-01-31 | WebSocket sessions fall back to HTTPS after the retries run out. |
| v0.162.0 | 2026-10-08 | Custom Responses providers can set capabilities.remote_compaction. |
Should you raise the retries?#
Raise stream_max_retries and stream_idle_timeout_ms when a custom provider, a gateway or a local model is slow or drops long responses: the extra attempts cost only time. Do not raise them for the server answers in the last rows of the table: no credits, a wrong Azure deployment and a full context window fail the same way on every attempt. On the built-in OpenAI provider the retry count is fixed, so a repeating error there points to the network path or to an OpenAI incident.
FAQ#
Q: What does "stream disconnected before completion" mean in Codex?
A: The model response stopped before Codex received the final response.completed event, and 5 automatic retries also failed. The text after the colon is the reason.
Q: What does "error decoding response body" mean?
A: The connection broke while Codex was reading the response. A VPN, a corporate proxy or an unstable network is the usual cause.
Q: What does "Error running remote compact task" mean?
A: Codex was compacting a long conversation on the server, and that request failed. Remote compaction retries at most 2 times. Codex keeps the message you sent, so you can send it again.
Q: How do I increase stream_max_retries in Codex?
A: Add stream_max_retries = 10 to your provider's [model_providers.<id>] table in ~/.codex/config.toml. The limit is 100. The built-in openai provider cannot be changed and uses 5.
Q: What is the default stream_idle_timeout_ms?
A: 300,000 milliseconds, which is 5 minutes.
Q: Why does Codex show "Reconnecting... 2/5"?
A: The stream dropped and Codex is retrying the turn. 5 is the default stream_max_retries. If all 5 fail on WebSockets, Codex falls back to HTTPS before it shows the error.
Q: Does retrying fix "you have no credits remaining"?
A: No. Add credits to the API account, or sign in with ChatGPT instead.
Sources: [1] Codex retry logic, rust-v0.166.0 | [2] Codex provider defaults, rust-v0.166.0 | Codex advanced configuration | Retry tuning, openai/codex #1956
Related: Codex config.toml reference | Codex CLI version tracker | Codex CLI v0.162.0 analysis | Codex CLI v0.166.0 analysis