Torna alle guide
Risoluzione dei problemi·23 settembre 2026·6 min di lettura

Codex “stream disconnected before completion” — cosa ha terminato lo stream e cosa ritenta Codex automaticamente

Codex stava leggendo uno stream Responses, o tentando di aprirne uno, e questo è terminato prima che arrivasse l’evento response.completed: la connessione si è chiusa, è rimasta silenziosa, si è interrotta a livello di rete oppure il server ha segnalato un errore. Codex ritenta automaticamente, cinque volte per impostazione predefinita. Il motivo stampato dopo i due punti indica quale di questi casi si è verificato e determina dove cercare.

Ultima revisione: .

Codex stava leggendo uno stream Responses, o tentando di aprirne uno, e questo è terminato prima che arrivasse l’evento response.completed: la connessione si è chiusa, è rimasta silenziosa, si è interrotta a livello di rete oppure il server ha segnalato un errore. Codex ritenta automaticamente, cinque volte per impostazione predefinita. Il motivo stampato dopo i due punti indica quale di questi casi si è verificato e determina dove cercare.

L’errore

Output di Codex (la disposizione varia in base al client)
# 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

Cause e soluzioni in breve

CausaSoluzione
Una VPN, un proxy, un firewall o un intermediario che ispeziona TLS ha chiuso la connessioneRitenta da un’altra rete; se l’errore scompare, escludi l’host API da quel proxy o dall’ispezione.
Il server ha avuto un errore durante la risposta — il motivo è il messaggio del server stessoNon c’è nulla da modificare localmente: lascia che Codex ritenti, controlla lo stato del provider e riprova più tardi.
Non è arrivato nulla per stream_idle_timeout_ms (300.000 ms per impostazione predefinita)Un upstream bloccato o un proxy che bufferizza; aumenta il timeout solo per silenzi legittimi.
Un provider personalizzato che termina gli stream senza response.completedEsegui curl -N contro di esso: ogni risposta riuscita deve terminare con quell’evento.
La risposta è stata terminata intenzionalmente — "Incomplete response returned"Un limite di token, un filtro dei contenuti o un altro motivo indicato dal motivo di arresto. Un ritentativo di solito lo ripete, quindi modifica la richiesta.

Leggi il motivo dopo i due punti

Codex usa questo unico errore per uno stream che termina prematuramente senza una diagnosi più specifica e aggiunge il motivo. Nel suo codice, uno stream che termina semplicemente restituisce "stream closed before response.completed"; uno che resta silenzioso più a lungo di stream_idle_timeout_ms restituisce "idle timeout waiting for SSE" ("idle timeout waiting for websocket" sul trasporto WebSocket usato dal provider OpenAI integrato); una richiesta che si interrompe sulla rete mantiene la formulazione del client HTTP, "error sending request" (le build precedenti alla 0.156 aggiungono l’URL); e un evento generico response.failed inserisce il messaggio del server dopo i due punti. Dalla versione 0.148 di Codex, una connessione che non può essere aperta affatto — DNS, TLS, porta rifiutata — viene segnalata come errore separato, "Connection failed", che le build attuali continuano a ritentare mentre attendono la rete.

what each reason means
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

Sappi cosa ritenta già Codex e regolalo per provider

Si applicano due budget di ritentativo. request_max_retries (predefinito 4) copre la richiesta HTTP prima che esista uno stream; Codex ritenta le risposte 5xx e gli errori di trasporto, ma non i 429. stream_max_retries (predefinito 5) copre tutto ciò che è descritto in questa pagina: ogni ritentativo reinvia il turno, ed è ciò che conta "Reconnecting... 1/5"; quando il budget si esaurisce, l’errore resta sullo schermo e il turno si interrompe. Entrambi hanno un limite di 100 ed entrambi risiedono in un blocco [model_providers.<id>]. L’ID del provider openai integrato è riservato e non può essere ridefinito, quindi queste impostazioni servono per i provider personalizzati.

~/.codex/config.toml
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)

Riproduci lo stream senza Codex

Uno stream Responses termina con un evento terminale e Codex richiede che sia response.completed. Invia lo stesso tipo di richiesta con curl dalla stessa macchina. Se si completa ogni volta mentre Codex continua a disconnettersi, controlla la build di Codex e le issue aperte; se anche curl si interrompe, ripeti da un’altra rete prima di accusare il provider. Nota quando si verificano gli errori: una caduta allo stesso tempo trascorso in ogni esecuzione indica un timer lungo il percorso, non una rete instabile.

reproduce.sh
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"

Escludi il percorso di rete, poi controlla il provider

Esegui il test da una seconda rete prima di trarre conclusioni. Nel forum OpenAI, gli errori di un utente su una macchina di lavoro sono cessati appena ha disabilitato Zscaler aziendale; in una discussione su GPT-5.6, quelli di un utente sono scomparsi usando una VPN o l’hotspot del telefono, mentre quelli di un altro sono persistiti dopo il cambio di rete. Se un’altra rete risolve il problema, escludi l’host API dal proxy o dall’ispezione TLS anziché aumentare i timeout. Per un provider personalizzato, codex doctor segnala se la configurazione è stata caricata e se è presente la variabile della chiave del provider; il provider deve servire la Responses API, poiché wire_api non ha altri valori, e supports_websockets deve rimanere non impostato salvo che esegua il trasporto Responses WebSocket. Se curl completa correttamente e Codex continua a fallire, aggiungi la riproduzione alle issue openai/codex #41340 o #41989, che segnalano questo errore con provider Responses personalizzati che trasmettono correttamente al di fuori di Codex e risultavano aperte il 23 settembre 2026.

Se chiami tramite Kunavo

Attraverso Kunavo, lo stream /v1/responses di un modello GPT è lo stream di eventi dell’upstream, inoltrato frame per frame: viene riscritto solo l’ID del modello e Kunavo non aggiunge eventi keepalive. Finché non arriva il primo evento di output, per un massimo di 30 secondi, lo stream viene trattenuto; quindi un upstream che in quella fase restituisce un errore, va in timeout o chiude la connessione può ancora essere ritentato sul canale successivo del modello, se configurato. Se nessun canale lo serve, Codex riceve un errore HTTP anziché uno stream — 502 quando l’upstream ha avuto un errore, non ha mai risposto o ha rifiutato la chiave usata da Kunavo, con la causa nel codice JSON, come upstream_524 o upstream_403 (qualsiasi altro 4xx dell’upstream conserva il proprio status) — che Codex stampa come unexpected status 502 Bad Gateway: Upstream provider error, non come questo messaggio, e ritenta anch’esso. Dopo il primo evento di output non è possibile ritentare senza duplicare l’output: un upstream response.failed passa attraverso come inviato, quindi Codex lo gestisce esattamente come se provenisse direttamente da OpenAI (un errore generico stampa il relativo messaggio dopo i due punti), mentre una connessione upstream che cade durante la risposta termina lo stream di Kunavo senza evento terminale, cosa che Codex segnala come stream closed before response.completed. In entrambi i casi subentrano i ritentativi di Codex. Nulla sul lato Kunavo limita uno stream che continua a fluire — il limite di 240 secondi copre solo l’attesa degli header upstream — ma il silenzio ne termina uno: Kunavo smette di leggere un upstream che non invia nulla per 300 secondi, come il timeout di inattività predefinito di Codex, e l’edge chiude una connessione che non trasporta byte per 600 secondi. Ognuno di questi errori viene registrato a costo zero. Il blocco del provider configurato sopra è quello impostato nella pagina di integrazione della CLI di Codex.

Domande frequenti

Cosa significa “stream closed before response.completed”?

La risposta HTTP è iniziata e la connessione è poi terminata senza l’evento response.completed che Codex attende. Qualcosa l’ha chiusa prematuramente: un proxy o un firewall lungo il percorso, il server oppure un endpoint personalizzato che non invia mai quell’evento.

Codex ritenta automaticamente “stream disconnected before completion”?

Sì. Codex reinvia il turno fino a stream_max_retries volte (5 per impostazione predefinita, 100 al massimo) e durante l’operazione mostra Reconnecting... 1/5. Quando il budget si esaurisce, l’errore resta sullo schermo e il turno si interrompe; l’invio di un altro messaggio avvia una nuova richiesta.

Devo aumentare stream_idle_timeout_ms?

Solo quando il motivo è "idle timeout waiting for SSE" e il silenzio è legittimo. Non serve a nulla per "stream closed before response.completed", dove la connessione è terminata anziché restare silenziosa. Attraverso Kunavo, valori superiori a 300000 non servono a nulla una volta iniziato lo stream: Kunavo smette di leggere un upstream che non invia nulla per 300 secondi e termina il tuo stream.

Perché Codex dice “Incomplete response returned, reason: max_output_tokens”?

Il server ha interrotto la risposta al proprio limite di token e lo ha indicato con un evento response.incomplete. Codex lo segnala con lo stesso errore e lo ritenta; un ritentativo dello stesso turno raggiunge di solito lo stesso limite, quindi dividi l’attività oppure usa un modello con un limite di output maggiore. Attraverso Kunavo, l’arresto per max-token di un modello Claude raggiunge Codex allo stesso modo.

Mi vengono addebitati i ritentativi?

Ogni ritentativo è una nuova richiesta. Attraverso Kunavo, una chiamata GPT che fallisce sull’upstream — un errore prima dello streaming, un response.failed, una connessione interrotta — viene registrata a costo zero. Un tentativo a cui Codex ha rinunciato mentre l’upstream continuava a funzionare viene addebitato per quanto l’upstream dichiara di aver prodotto, perché quel lavoro è stato eseguito.

Guide correlate

Ulteriori dettagli sul significato degli errori sono disponibili in riferimento agli errori; ottenere una chiave richiede un minuto tramite registrazione e la guida all’autenticazione.