Codex stream disconnected before completion: two causes, one message

Model: Kimi K3

Five reconnects, then this:

ERROR: stream disconnected before completion: stream closed before response.completed

That is the whole error. I hit it twice on 27 October 2026 with codex-cli 0.154.0, once with a revoked key and once with a base URL missing its /v1. Both runs printed the same six lines. Neither printed a 401.

Disclosure: Wallaby Token sells API access to Kimi K3, the endpoint used for every test below.

Codex is not wrong to retry. A stream that dies mid-response is usually a network problem, so the client reconnects before giving up. The side effect is that an authentication failure and a routing failure arrive as the same symptom, and the message sends you looking for a proxy.

The triage table

Every line below is trimmed from a terminal session on 27 October 2026, against one OpenAI-compatible endpoint. Start at the row that matches your output.

What you see What it means Fix
Missing environment variable: WALLABY_API_KEY The env_key in your provider block is not set in the shell that launched Codex Export it in the same shell, or set it in the environment Codex inherits
Reconnecting... 1/5 through 5/5, then stream disconnected before completion The endpoint rejected the request before the stream opened. In our runs, a bad key did this, and so did a base URL missing /v1. Run the curl check below before touching the config
unexpected status 404 Not Found: Invalid URL (POST /v1/v1/responses) base_url contains a duplicate /v1, so the request goes to /v1/v1/responses and the API has no such route Remove the duplicate segment
model 'x' is not supported on this endpoint. Available: kimi-k3 The model id is not one this endpoint serves Use an id from /v1/models
Error: Model provider 'wallabyy' not found The model_provider name does not match a [model_providers.*] block Fix the spelling in both places
wire_api = "chat" is no longer supported Codex removed chat-completions support Set wire_api = "responses"

Case 1: the key is dead

The CLI output is identical to a network failure:

ERROR: Reconnecting... 1/5
ERROR: Reconnecting... 2/5
ERROR: Reconnecting... 3/5
ERROR: Reconnecting... 4/5
ERROR: Reconnecting... 5/5
ERROR: stream disconnected before completion: stream closed before response.completed

The endpoint tells a different story. Ask it directly:

curl -i https://api.wallabytoken.com/v1/responses \
  -H "Authorization: Bearer $WALLABY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"kimi-k3","input":"hi"}'

A dead key returns HTTP/2 401 and a JSON error body. A live key returns HTTP/2 200 and a response object. Codex showed you neither.

That check takes one second and saves the twenty minutes you would spend editing config.toml to fix a key that was never going to work.

Case 2: the base URL is the wrong shape

base_url should stop at /v1. Codex appends /responses itself.

Two shapes failed here, and they failed differently. With https://api.wallabytoken.com and no /v1, the request landed on a path the server does not serve, and the CLI produced the reconnect loop from Case 1. With https://api.wallabytoken.com/v1/v1, the URL was recognizable enough to surface:

ERROR: unexpected status 404 Not Found: Invalid URL (POST /v1/v1/responses), url: https://api.wallabytoken.com/v1/v1/responses

Without /v1, the request landed on https://api.wallabytoken.com/responses, which is the website. It answered 200 with text/html in our test. Codex expected an event stream, got a page, and reported the stream as closed. With the doubled path the request reached the API layer, which answered 404 with a message the client could print.

Same root cause, different visibility. If your URL ends in /v1, do not add another one.

Case 3: config errors that do speak

Not every mistake hides. These three print a clear message before any request goes out.

First, an unset variable. The provider block names env_key = "WALLABY_API_KEY", but the key lives only in your notes:

ERROR: Missing environment variable: `WALLABY_API_KEY`.

Second, a provider name that does not resolve. This one comes from the profile, not the network:

Error: Model provider `wallabyy` not found

Third, the old wire format. Every guide written before Codex dropped chat completions will trigger it:

Error loading config.toml: `wire_api = "chat"` is no longer supported.
How to fix: set `wire_api = "responses"` in your provider config.

Case 4: a model id the endpoint does not serve

This one returns a JSON error from the server, not a stream failure:

model 'kimi-k3-nope' is not supported on this endpoint. Available: kimi-k3

The endpoint knows what it serves. Ask it:

curl -s https://api.wallabytoken.com/v1/models \
  -H "Authorization: Bearer $WALLABY_API_KEY"

The response lists kimi-k3 and moonshotai/kimi-k3. Anything else gets the error above.

The two-minute check

Run these three commands in order. The first two isolate the endpoint from the client, so the third only has one job.

# 1. Is the key alive and the URL right?
curl -s -o /dev/null -w "%{http_code}\n" https://api.wallabytoken.com/v1/models \
  -H "Authorization: Bearer $WALLABY_API_KEY"

# 2. Does the model answer a one-line request?
curl -s https://api.wallabytoken.com/v1/responses \
  -H "Authorization: Bearer $WALLABY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"kimi-k3","input":"Reply with OK"}'

# 3. Now let Codex use the same values.
codex exec \
  -c 'model_providers.wallaby={name="Wallaby", base_url="https://api.wallabytoken.com/v1", env_key="WALLABY_API_KEY", wire_api="responses"}' \
  -c model_provider="wallaby" \
  -c model="kimi-k3" \
  "Reply with exactly: OK"

If step 1 returns 200 and step 2 returns a response object, the endpoint is fine and the problem is in the Codex config. If step 1 returns 401, stop there.

One warning is normal. Every run prints Model metadata for 'kimi-k3' not found. Defaulting to fallback metadata. It appears on successful runs too, including the one that printed OK.

Scope

These results are from codex-cli 0.154.0 on macOS, against an endpoint that speaks the Responses API. 0.164.0 was current when this was checked; the cases here were not re-run on it. The ChatGPT login path, corporate proxies, and self-hosted gateways were not tested. The reconnect loop stops at five in this build, so a future release may surface the status line directly.

If you want a live endpoint to test against, a new Wallaby Token account comes with $0.50 in trial credit. The minimum top-up is $20, and the rate stays 10% off the official list. Every request is itemized, so you can check the 401 and the 200 against your own meter.

Like the Dispatch? Add Wallaby as a preferred source on Google, or subscribe via RSS.
Did this help?