Codex 正在讀取 Responses 串流,或嘗試開啟串流,而它在 response.completed 事件抵達前就結束了:連線可能關閉、陷入無回應、在網路層中斷,或伺服器回報失敗。Codex 預設會自行重試五次。冒號後印出的原因會告訴你發生的是哪一種情況,並決定應該從哪裡檢查。
錯誤
# Codex CLI, once its retries are spent
■ stream disconnected before completion: stream closed before response.completed
# While it retries (VS Code extension, an early-2026 build)
Reconnecting... 1/5
stream disconnected before completion: error sending request for url (https://…/responses)
# The reason after the colon varies, and it is the diagnosis:
# stream closed before response.completed
# idle timeout waiting for SSE
# error sending request (Codex before 0.156 adds: for url (…))
# An error occurred while processing your request. You can retry your request, …
# Incomplete response returned, reason: max_output_tokens原因與解決方法一覽
| 原因 | 解決方法 |
|---|---|
| VPN、代理伺服器、防火牆或 TLS 檢查中介設備關閉了連線 | 改用另一個網路重試;如果錯誤消失,請將 API 主機從該代理伺服器或檢查中排除。 |
| 伺服器在回應途中失敗 — 原因是伺服器自己的訊息 | 本機不需要變更:讓 Codex 重試,檢查供應商狀態,稍後再試。 |
| 在 stream_idle_timeout_ms(預設 300,000 ms)期間沒有收到任何內容 | 上游停滯或代理伺服器緩衝;只有在無回應屬於合理情況時才提高逾時值。 |
| 自訂供應商在沒有 response.completed 的情況下結束串流 | 對其執行 curl -N:每個成功回應都必須以該事件結束。 |
| 回應是刻意結束的 — 「Incomplete response returned」 | 原因會指出 token 上限、內容篩選器或其他停止原因。重試通常會重現相同結果,因此請改變請求。 |
讀取冒號後的原因
Codex 對於沒有更具體診斷、提早結束的串流使用這個錯誤,並附加原因。在其原始碼中,單純結束的串流會給出「stream closed before response.completed」;比 stream_idle_timeout_ms 更久沒有回應的串流會給出「idle timeout waiting for SSE」(內建 OpenAI 供應商使用的 WebSocket 傳輸則是「idle timeout waiting for websocket」);在網路上中斷的請求會保留 HTTP 用戶端措辭「error sending request」(0.156 以前的版本會加入 URL);一般的 response.failed 事件則會在冒號後放上伺服器訊息。從 Codex 0.148 起,完全無法開啟的連線 — DNS、TLS、連線埠遭拒 — 會回報為獨立錯誤「Connection failed」,目前版本會在等待網路時持續重試。
stream closed before response.completed the connection ended with no terminal event:
network path, server, or a provider that
never sends response.completed
idle timeout waiting for SSE no event for stream_idle_timeout_ms
error sending request the request broke on the wire: a reset, a
proxy or a middlebox (before 0.148, also
a connection that never opened)
…error decoding response body the body broke mid-read: network or middlebox
An error occurred while processing… the server's own response.failed message
Incomplete response returned, reason: … the server stopped it: a token cap, a content
filter, or whatever the reason names了解 Codex 已會重試的內容,並按供應商調整設定
有兩組重試預算適用。request_max_retries(預設 4)涵蓋串流建立前的 HTTP 請求;Codex 會在此重試 5xx 回應及傳輸錯誤,但不會重試 429。stream_max_retries(預設 5)涵蓋本頁所有情況:每次重試都會重新送出該回合,這就是「Reconnecting... 1/5」所計算的內容;預算用盡後,錯誤會保留在畫面上,回合停止。兩者上限都是 100,且都位於 [model_providers.<id>] 區塊中。內建的 openai 供應商 ID 是保留值,無法重新定義,因此這些是自訂供應商可調整的設定。
model = "gpt-5-6-sol"
model_provider = "kunavo"
[model_providers.kunavo]
name = "Kunavo"
base_url = "https://api.kunavo.com/v1"
env_key = "KUNAVO_API_KEY"
# wire_api defaults to "responses", the only supported value
stream_max_retries = 10 # dropped or failed streams (default 5, max 100)
request_max_retries = 4 # 5xx and network errors before streaming (default 4, max 100)
stream_idle_timeout_ms = 300000 # silence before giving up (default 300000)不使用 Codex 重現串流
Responses 串流會以一個終止事件結束,而 Codex 要求該事件為 response.completed。使用同一台機器上的 curl 傳送相同類型的請求。如果它每次都能完成,而 Codex 持續中斷,請檢查 Codex 建置版本及其公開 issue;如果 curl 也中斷,請先從另一個網路重試,再歸咎於供應商。記錄失敗發生的時機:如果每次執行都在相同經過時間中斷,表示路徑上的某處有計時器,而不是網路不穩定。
curl -sN https://api.kunavo.com/v1/responses \
-H "Authorization: Bearer $KUNAVO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-5-6-sol","stream":true,
"input":"Write a 600-word story about a lighthouse keeper."}' \
| grep -oE '"type": ?"response\.(completed|failed|incomplete)"'
# a healthy run prints exactly one line: "type":"response.completed"先排除網路路徑,再檢查供應商
下結論前,先從第二個網路進行測試。在 OpenAI 論壇中,有一位使用者在工作機器上的錯誤於停用公司 Zscaler 後立即停止;在一個 GPT-5.6 討論串中,一位使用者的錯誤在使用 VPN 或手機熱點後消失,另一位使用者則在切換網路後仍持續發生。如果另一個網路能修正問題,請將 API 主機從代理伺服器或 TLS 檢查中排除,而不是提高逾時值。對於自訂供應商,codex doctor 會回報設定是否載入,以及供應商的金鑰變數是否存在;供應商必須提供 Responses API,因為 wire_api 沒有其他值;除非它執行 Responses WebSocket 傳輸,否則應保持 supports_websockets 未設定。如果 curl 能順利完成,而 Codex 仍失敗,請將重現資訊加入 openai/codex issue #41340 或 #41989;這些 issue 回報了自訂 Responses 供應商出現的此錯誤,這些供應商在 Codex 外部能正確串流,而這些 issue 截至 2026 年 9 月 23 日仍未關閉。
如果你透過 Kunavo 呼叫
透過 Kunavo,GPT 模型的 /v1/responses 串流是上游自身的事件串流,由 Kunavo 逐幀轉送:只有模型 ID 會被改寫,Kunavo 不會加入 keepalive 事件。在第一個輸出事件抵達前,串流最多會被暫存 30 秒,因此在此階段發生錯誤、逾時或中斷的上游,仍可在已設定其他通道時於模型的下一個通道重試。若沒有任何通道能提供該模型,Codex 會收到 HTTP 錯誤而非串流 — 當上游發生錯誤、從未回應,或拒絕 Kunavo 自身的金鑰時會回傳 502;原因位於 JSON code 中,例如 upstream_524 或 upstream_403(任何其他上游 4xx 都會保留自身狀態)— Codex 會將其列印為 unexpected status 502 Bad Gateway: Upstream provider error,而不是本訊息,並同樣重試。第一個輸出事件之後,若要重試就會重複輸出,因此無法再進行重試:上游的 response.failed 會以已傳送狀態直接通過,所以 Codex 會完全按照直接來自 OpenAI 的情況處理(一般失敗會在冒號後列印其訊息);而上游連線若在回答途中中斷,Kunavo 的串流會在沒有終止事件的情況下結束,Codex 會回報 stream closed before response.completed。無論哪種情況,接著都由 Codex 自身的重試機制接手。Kunavo 不會限制持續流動的串流 — 240 秒限制只涵蓋等待上游標頭;但無回應會結束串流:如果上游 300 秒都沒有傳送任何內容,Kunavo 會停止讀取,這與 Codex 的閒置預設值相同;而不含任何位元組的連線持續 600 秒後,邊緣節點會關閉連線。每一種失敗都會以零成本記錄。 上方調整的提供者區塊,就是在 Codex CLI 整合頁面上設定的區塊.
常見問題
「stream closed before response.completed」是什麼意思?
HTTP 回應已開始,但連線隨後在 response.completed 事件出現前結束;Codex 會等待此事件。某個元件提前將其關閉:途中經過的 Proxy 或防火牆、伺服器,或從未傳送該事件的自訂端點。
Codex 會自動重試「stream disconnected before completion」嗎?
會。Codex 會重新傳送該回合,最多重試 stream_max_retries 次(預設為 5 次,最多 100 次),重試期間會顯示 Reconnecting... 1/5。額度用完後,錯誤會持續顯示在畫面上,該回合也會停止;再傳送另一則訊息會開始新的請求。
我應該提高 stream_idle_timeout_ms 嗎?
只有在原因是「idle timeout waiting for SSE」,且靜默狀態確實合理時才需要。對於「stream closed before response.completed」則沒有作用,因為該情況是連線結束,而不是變得安靜。透過 Kunavo,串流開始後,將值設為 300000 以上也沒有任何好處:Kunavo 會在上游連續 300 秒沒有傳送任何內容後停止讀取,並結束你的串流。
為什麼 Codex 會說「Incomplete response returned, reason: max_output_tokens」?
伺服器在達到其 token 上限時停止回應,並透過 response.incomplete 事件說明原因。Codex 會以相同錯誤回報並重試,而相同回合的重試通常會再次遇到相同上限,因此請拆分任務,或使用輸出上限更高的模型。透過 Kunavo,Claude 模型因 max-token 停止時,也會以相同方式傳到 Codex。
重試會向我收費嗎?
每次重試都是新的請求。透過 Kunavo,上游失敗的 GPT 呼叫——串流前發生錯誤、response.failed,或連線中斷——會以零成本記錄。若 Codex 放棄嘗試時上游仍在運作,則會依上游回報已產生的內容計費,因為那些工作已經完成。