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.