Volver a las guías
Solución de problemas·23 de septiembre de 2026·6 min de lectura

«stream disconnected before completion» de Codex: qué terminó el flujo y qué reintenta Codex por su cuenta

Codex estaba leyendo un flujo de Responses, o intentando abrir uno, y terminó antes de que llegara el evento response.completed: la conexión se cerró, quedó en silencio, falló a nivel de red o el servidor informó de un error. Codex lo reintenta por su cuenta, cinco veces de forma predeterminada. El motivo impreso después de los dos puntos indica cuál de esas situaciones ocurrió y determina dónde buscar.

Última revisión: .

Codex estaba leyendo un flujo de Responses, o intentando abrir uno, y terminó antes de que llegara el evento response.completed: la conexión se cerró, quedó en silencio, falló a nivel de red o el servidor informó de un error. Codex lo reintenta por su cuenta, cinco veces de forma predeterminada. El motivo impreso después de los dos puntos indica cuál de esas situaciones ocurrió y determina dónde buscar.

El error

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

Causas y soluciones de un vistazo

CausaSolución
Una VPN, un proxy, un firewall o un intermediario que inspecciona TLS cerró la conexiónReintenta desde otra red; si el error desaparece, excluye el host de la API de ese proxy o de la inspección.
El servidor falló a mitad de la respuesta; el motivo es el propio mensaje del servidorNo cambies nada localmente: deja que Codex reintente, comprueba el estado del proveedor y vuelve a intentarlo más tarde.
No llegó nada durante stream_idle_timeout_ms (300,000 ms de forma predeterminada)Un upstream bloqueado o un proxy que almacena en búfer; aumenta el tiempo de espera solo para silencios legítimos.
Un proveedor personalizado que termina los flujos sin response.completedEjecuta curl -N contra él: toda respuesta correcta debe terminar con ese evento.
La respuesta terminó intencionadamente: «Incomplete response returned»Un límite de tokens, un filtro de contenido u otra causa de detención que indique el motivo. Un reintento normalmente lo repite, así que cambia la solicitud.

Lee el motivo después de los dos puntos

Codex utiliza este único error para un flujo que termina prematuramente sin un diagnóstico más específico y añade el motivo. En su código, un flujo que simplemente termina muestra «stream closed before response.completed»; uno que permanece en silencio más tiempo que stream_idle_timeout_ms muestra «idle timeout waiting for SSE» («idle timeout waiting for websocket» en el transporte WebSocket que utiliza el proveedor OpenAI integrado); una solicitud que falla en el cable conserva el texto del cliente HTTP, «error sending request» (las compilaciones anteriores a 0.156 añaden la URL); y un evento genérico response.failed coloca el mensaje del servidor después de los dos puntos. Desde Codex 0.148, una conexión que no se puede abrir en absoluto —DNS, TLS o un puerto rechazado— se informa como un error separado, «Connection failed», que las compilaciones actuales siguen reintentando mientras esperan a la red.

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

Sabe qué reintenta ya Codex y ajústalo por proveedor

Se aplican dos presupuestos de reintentos. request_max_retries (4 de forma predeterminada) cubre la solicitud HTTP antes de que exista ningún flujo; Codex reintenta respuestas 5xx y errores de transporte allí, pero no los 429. stream_max_retries (5 de forma predeterminada) cubre todo lo de esta página: cada reintento vuelve a enviar el turno, que es lo que cuenta «Reconnecting... 1/5», y cuando se agota el presupuesto, el error permanece en pantalla y el turno se detiene. Ambos están limitados a 100 y ambos viven en un bloque [model_providers.<id>]. El ID de proveedor integrado openai está reservado y no se puede redefinir, por lo que estos parámetros son para proveedores personalizados.

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

Reproduce el flujo sin Codex

Un flujo de Responses termina con un evento terminal, y Codex necesita que sea response.completed. Envía el mismo tipo de solicitud con curl desde la misma máquina. Si se completa siempre mientras Codex sigue desconectándose, revisa la compilación de Codex y sus problemas abiertos; si curl también falla, repítelo desde otra red antes de culpar al proveedor. Observa cuándo ocurren los fallos: una caída en el mismo tiempo transcurrido en todas las ejecuciones apunta a un temporizador en algún punto del trayecto, no a una red inestable.

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"

Elimina el trayecto de red y luego comprueba el proveedor

Prueba desde una segunda red antes de concluir nada. En el foro de OpenAI, los errores de un usuario en una máquina de trabajo desaparecieron en cuanto desactivó el Zscaler de la empresa; en un hilo sobre GPT-5.6, los de un usuario desaparecieron con una VPN o un punto de acceso del teléfono, mientras que los de otro persistieron después de cambiar de red. Si otra red lo soluciona, excluye el host de la API del proxy o de la inspección TLS en lugar de aumentar los tiempos de espera. Para un proveedor personalizado, codex doctor informa de si se cargó la configuración y de si está presente la variable de la clave del proveedor; el proveedor debe servir la API de Responses, ya que wire_api no tiene otro valor, y supports_websockets debe permanecer sin definir salvo que ejecute el transporte Responses WebSocket. Si curl se completa correctamente y Codex sigue fallando, añade tu reproducción a los problemas #41340 o #41989 de openai/codex, que informan de este error contra proveedores personalizados de Responses que transmiten correctamente fuera de Codex y estaban abiertos el 23 de septiembre de 2026.

Si llamas a través de Kunavo

A través de Kunavo, el flujo /v1/responses de un modelo GPT es el propio flujo de eventos del upstream, retransmitido trama por trama: solo se reescribe el ID del modelo y Kunavo no añade eventos de mantenimiento de conexión. Hasta que llega el primer evento de salida, durante un máximo de 30 segundos, el flujo se retiene, por lo que un upstream que falla, agota el tiempo de espera o cuelga la conexión en esa etapa todavía puede reintentarse en el siguiente canal del modelo cuando haya uno configurado. Si ninguno lo sirve, Codex recibe un error HTTP en lugar de un flujo: un 502 cuando el upstream falló, nunca respondió o rechazó la propia clave de Kunavo, con la causa en el código JSON, como upstream_524 o upstream_403 (cualquier otro 4xx del upstream conserva su propio estado); Codex lo imprime como unexpected status 502 Bad Gateway: Upstream provider error, no como este mensaje, y también lo reintenta. Después del primer evento de salida, ya no se puede reintentar nada sin duplicar la salida: un response.failed del upstream pasa tal cual, por lo que Codex lo gestiona exactamente como si proviniera directamente de OpenAI (un fallo genérico imprime su mensaje después de los dos puntos), y una conexión del upstream que se interrumpe a mitad de la respuesta termina el flujo de Kunavo sin evento terminal, lo que Codex informa como stream closed before response.completed. En ambos casos, toman el control los propios reintentos de Codex. Nada del lado de Kunavo limita un flujo que sigue transmitiendo; el límite de 240 segundos cubre únicamente la espera de las cabeceras del upstream, pero el silencio sí termina uno: Kunavo deja de leer un upstream que no envía nada durante 300 segundos, igual que el valor de inactividad predeterminado de Codex, y el edge cierra una conexión que no transporta bytes durante 600 segundos. Cada uno de esos fallos se registra con coste cero. El bloque del proveedor configurado arriba es el que se establece en la página de integración de Codex CLI.

Preguntas frecuentes

¿Qué significa “stream closed before response.completed”?

La respuesta HTTP comenzó y la conexión terminó después sin el evento response.completed que Codex espera. Algo la cerró antes de tiempo: un proxy o firewall intermedio, el servidor o un endpoint personalizado que nunca envía ese evento.

¿Codex reintenta automáticamente “stream disconnected before completion”?

Sí. Codex vuelve a enviar el turno hasta stream_max_retries veces (5 de forma predeterminada, 100 como máximo) y muestra Reconnecting... 1/5 mientras lo hace. Cuando se agota el presupuesto, el error permanece en pantalla y el turno se detiene; enviar otro mensaje inicia una nueva solicitud.

¿Debo aumentar stream_idle_timeout_ms?

Solo cuando el motivo sea "idle timeout waiting for SSE" y el silencio sea legítimo. No sirve para "stream closed before response.completed", donde la conexión terminó en lugar de permanecer inactiva. A través de Kunavo, los valores superiores a 300000 no aportan nada una vez iniciado el flujo: Kunavo deja de leer un upstream que no envía nada durante 300 segundos y finaliza tu flujo.

¿Por qué Codex dice “Incomplete response returned, reason: max_output_tokens”?

El servidor detuvo la respuesta al alcanzar su límite de tokens y lo indicó mediante un evento response.incomplete. Codex lo informa con el mismo error y lo reintenta, pero un reintento del mismo turno normalmente vuelve a alcanzar el mismo límite; divide la tarea o usa un modelo con un límite de salida mayor. A través de Kunavo, una detención por max-tokens de un modelo Claude llega a Codex de la misma manera.

¿Se me cobra por los reintentos?

Cada reintento es una nueva solicitud. A través de Kunavo, una llamada GPT que falla en el upstream —un error antes del streaming, un response.failed o una conexión interrumpida— se registra con coste cero. Un intento al que Codex renunció mientras el upstream seguía trabajando se factura según lo que el upstream indique que produjo, porque ese trabajo se realizó.

Guías relacionadas

Encontrarás más detalles sobre el significado de los errores en referencia de errores; obtener una clave lleva un minuto mediante registro y la guía de autenticación.