Retour aux guides
Dépannage·23 septembre 2026·6 min de lecture

Codex « stream disconnected before completion » — ce qui a interrompu le flux et ce que Codex réessaie automatiquement

Codex lisait un flux Responses, ou tentait d'en ouvrir un, et celui-ci s'est terminé avant l'arrivée de l'événement response.completed : la connexion s'est fermée, est restée silencieuse, a rencontré une défaillance réseau ou le serveur a signalé une erreur. Codex réessaie automatiquement, cinq fois par défaut. La raison affichée après les deux-points indique ce qui s'est produit et détermine où chercher.

Dernière vérification le .

Codex lisait un flux Responses, ou tentait d'en ouvrir un, et celui-ci s'est terminé avant l'arrivée de l'événement response.completed : la connexion s'est fermée, est restée silencieuse, a rencontré une défaillance réseau ou le serveur a signalé une erreur. Codex réessaie automatiquement, cinq fois par défaut. La raison affichée après les deux-points indique ce qui s'est produit et détermine où chercher.

L’erreur

Codex output (layout varies by 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

Causes et solutions en bref

CauseSolution
Un VPN, un proxy, un pare-feu ou un intermédiaire inspectant TLS a fermé la connexionRéessayez depuis un autre réseau ; si l'erreur disparaît, excluez l'hôte de l'API de ce proxy ou de cette inspection.
Le serveur a échoué au milieu de la réponse — la raison est le propre message du serveurRien à modifier localement : laissez Codex réessayer, consultez l'état du fournisseur et réessayez plus tard.
Aucune donnée n'est arrivée pendant stream_idle_timeout_ms (300,000 ms par défaut)Un serveur en amont bloqué ou un proxy qui met les données en mémoire tampon ; augmentez le délai uniquement pour les silences légitimes.
Un fournisseur personnalisé qui termine les flux sans response.completedExécutez curl -N contre celui-ci : toute réponse réussie doit se terminer par cet événement.
La réponse a été terminée intentionnellement — « Incomplete response returned »Un plafond de tokens, un filtre de contenu ou une autre raison indiquée par le motif d'arrêt. Une nouvelle tentative le reproduit généralement ; modifiez donc la requête.

Lisez la raison après les deux-points

Codex utilise cette même erreur pour un flux qui se termine prématurément sans diagnostic plus précis, puis ajoute la raison. Dans son code source, un flux qui se termine simplement renvoie « stream closed before response.completed » ; un flux qui reste silencieux plus longtemps que stream_idle_timeout_ms renvoie « idle timeout waiting for SSE » (« idle timeout waiting for websocket » pour le transport WebSocket utilisé par le fournisseur OpenAI intégré) ; une requête interrompue sur le réseau conserve le libellé du client HTTP, « error sending request » (les versions antérieures à 0.156 ajoutent l'URL) ; et un événement response.failed générique place le message du serveur après les deux-points. Depuis Codex 0.148, une connexion qui ne peut pas être ouverte du tout — DNS, TLS, port refusé — est signalée comme une erreur distincte, « Connection failed », que les versions actuelles continuent de réessayer en attendant le réseau.

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

Sachez ce que Codex réessaie déjà et adaptez-le par fournisseur

Deux budgets de nouvelles tentatives s'appliquent. request_max_retries (4 par défaut) couvre la requête HTTP avant l'existence de tout flux ; Codex réessaie les réponses 5xx et les erreurs de transport dans ce cadre, mais pas les 429. stream_max_retries (5 par défaut) couvre tout ce qui figure sur cette page : chaque nouvelle tentative renvoie le tour, ce que compte « Reconnecting... 1/5 », et lorsque le budget est épuisé, l'erreur reste affichée et le tour s'arrête. Les deux valeurs sont plafonnées à 100 et se trouvent dans un bloc [model_providers.<id>]. L'identifiant du fournisseur openai intégré est réservé et ne peut pas être redéfini ; ces paramètres servent donc aux fournisseurs personnalisés.

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

Reproduisez le flux sans Codex

Un flux Responses se termine par un événement terminal, et Codex exige qu'il s'agisse de response.completed. Envoyez le même type de requête avec curl depuis la même machine. Si elle s'achève à chaque fois alors que Codex continue de se déconnecter, examinez la version de Codex et ses problèmes ouverts ; si curl échoue aussi, répétez le test depuis un autre réseau avant d'accuser le fournisseur. Notez le moment où surviennent les échecs : une interruption au même temps écoulé à chaque exécution indique un minuteur quelque part sur le chemin, et non un réseau instable.

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"

Écartez le chemin réseau, puis vérifiez le fournisseur

Testez depuis un deuxième réseau avant de tirer une conclusion. Sur le forum OpenAI, les erreurs d'un utilisateur sur une machine professionnelle ont cessé dès qu'il a désactivé le Zscaler de son entreprise ; dans un fil GPT-5.6, celles d'un utilisateur ont disparu avec un VPN ou un point d'accès téléphonique, tandis que celles d'un autre ont persisté après le changement de réseau. Si un autre réseau règle le problème, excluez l'hôte de l'API du proxy ou de l'inspection TLS plutôt que d'augmenter les délais. Pour un fournisseur personnalisé, codex doctor indique si la configuration a été chargée et si la variable de clé du fournisseur est présente ; le fournisseur doit servir l'API Responses, puisque wire_api n'a aucune autre valeur, et supports_websockets doit rester non défini sauf s'il exécute le transport Responses WebSocket. Si curl s'achève correctement et que Codex échoue toujours, ajoutez votre reproduction aux problèmes openai/codex #41340 ou #41989, qui signalent cette erreur avec des fournisseurs Responses personnalisés diffusant correctement en dehors de Codex et qui étaient ouverts le 23 septembre 2026.

Si vous appelez via Kunavo

Via Kunavo, le flux /v1/responses d'un modèle GPT est le propre flux d'événements de l'amont, relayé trame par trame : seul l'identifiant du modèle est réécrit et Kunavo n'ajoute aucun événement de maintien en vie. Jusqu'à l'arrivée du premier événement de sortie, pendant au plus 30 secondes, le flux est retenu ; ainsi, un amont qui génère une erreur, expire ou se déconnecte à ce stade peut encore être réessayé sur le canal suivant du modèle lorsqu'il est configuré. Si aucun canal ne le sert, Codex reçoit une erreur HTTP plutôt qu'un flux — 502 lorsque l'amont a généré une erreur, n'a jamais répondu ou a refusé la propre clé de Kunavo, avec la cause dans le code JSON, par exemple upstream_524 ou upstream_403 (tout autre 4xx de l'amont conserve son propre statut) — que Codex affiche sous la forme unexpected status 502 Bad Gateway: Upstream provider error, et non sous ce message, et qu'il réessaie également. Après le premier événement de sortie, aucune nouvelle tentative n'est possible sans dupliquer la sortie : une réponse upstream response.failed est transmise telle quelle, donc Codex la traite exactement comme si elle provenait directement d'OpenAI (un échec générique affiche son message après les deux-points), et une connexion amont qui s'interrompt au milieu de la réponse termine le flux Kunavo sans événement terminal, ce que Codex signale par stream closed before response.completed. Dans les deux cas, les nouvelles tentatives de Codex prennent le relais. Rien du côté de Kunavo ne plafonne un flux qui continue à produire des données — la limite de 240 secondes ne couvre que l'attente des en-têtes de l'amont — mais le silence en termine un : Kunavo cesse de lire un amont qui n'envoie rien pendant 300 secondes, comme la valeur d'inactivité par défaut de Codex, et le réseau edge ferme une connexion qui ne transporte aucun octet pendant 600 secondes. Chacun de ces échecs est enregistré sans frais. Le bloc fournisseur configuré ci-dessus se trouve sur la page d'intégration de l'interface CLI de Codex.

Questions fréquentes

Que signifie « stream closed before response.completed » ?

La réponse HTTP a commencé, puis la connexion s'est terminée sans l'événement response.completed que Codex attend. Quelque chose l'a fermée prématurément : un proxy ou un pare-feu sur le chemin, le serveur ou un endpoint personnalisé qui n'envoie jamais cet événement.

Codex réessaie-t-il automatiquement « stream disconnected before completion » ?

Oui. Codex renvoie le tour jusqu'à stream_max_retries fois (5 par défaut, 100 au maximum) et affiche Reconnecting... 1/5 pendant l'opération. Lorsque le budget est épuisé, l'erreur reste affichée et le tour s'arrête ; l'envoi d'un autre message démarre une nouvelle requête.

Dois-je augmenter stream_idle_timeout_ms ?

Uniquement lorsque la raison est « idle timeout waiting for SSE » et que le silence est légitime. Cela ne change rien pour « stream closed before response.completed », où la connexion s'est terminée au lieu de rester silencieuse. Via Kunavo, les valeurs supérieures à 300000 ne servent à rien une fois le flux commencé : Kunavo cesse de lire un amont qui n'envoie rien pendant 300 secondes et termine votre flux.

Pourquoi Codex indique-t-il « Incomplete response returned, reason: max_output_tokens » ?

Le serveur a arrêté la réponse à son plafond de tokens et l'a signalé par un événement response.incomplete. Codex le signale sous la même erreur et réessaie ; une nouvelle tentative du même tour atteint généralement le même plafond. Divisez donc la tâche ou utilisez un modèle disposant d'un plafond de sortie supérieur. Via Kunavo, l'arrêt pour dépassement du nombre maximal de tokens d'un modèle Claude parvient à Codex de la même manière.

Les nouvelles tentatives me sont-elles facturées ?

Chaque nouvelle tentative est une nouvelle requête. Via Kunavo, un appel GPT qui échoue en amont — une erreur avant la diffusion, une réponse response.failed ou une connexion interrompue — est enregistré sans frais. Une tentative à laquelle Codex a renoncé alors que l'amont continuait de fonctionner est facturée selon ce que l'amont indique avoir produit, puisque ce travail a été effectué.

Guides associés

La sémantique détaillée des erreurs est disponible dans référence des erreurs ; obtenir une clé prend une minute via inscription et la guide d’authentification.