HTTPQUERY
Español

408 Request Timeout

Uso

Cuando llega un error 408 Request Timeout, el cliente ha iniciado una solicitud pero, por algún motivo, no ha transmitido la carga útil completa. Esto ocurre cuando la conexión a internet es lenta o se ha caído. La respuesta incluye la cabecera Connection, que indica que la conexión se ha cerrado.

Al recibir la cabecera Connection: close, el cliente intenta la solicitud de nuevo.

Nota

408 Request Timeout significa que el cliente tardó demasiado en enviar la solicitud al servidor. 504 Gateway Timeout significa que un proxy o una pasarela agotó el tiempo de espera mientras aguardaba la respuesta del servidor backend. 408 es un tiempo de espera de cliente a servidor, mientras que 504 es un tiempo de espera de servidor a servidor. 408 es uno de los pocos códigos 4xx que justifican un reintento automático, ya que la causa suele ser transitoria.

Impacto en SEO

Los motores de búsqueda como Google no indexan una URL que devuelve un estado 408. Las URL indexadas previamente que devuelven este código de estado se eliminan de los resultados de búsqueda.

Ejemplo

El cliente empieza a enviar al servidor un archivo PDF de 10K, pero la conexión sufre problemas intermitentes de conectividad y el servidor concluye que la transmisión es demasiado lenta. El servidor cancela la solicitud y cierra la conexión. Cuando la conexión se estabiliza, el cliente retransmite el archivo con éxito.

Solicitud inicial

PUT /docs HTTP/1.1
Host: example.com
Content-Type: application/pdf
Content-Length: 10000

Respuesta inicial

HTTP/1.1 408 Request Timeout
Connection: Close
Content-Type: text/html
Content-Length: 198

<html>
  <head>
    <title>Connection Close</title>
  </head>
  <body>
    <p>The transmission was not received quickly
    enough. Check connectivity and try again.</p>
  </body>
</html>

Siguiente solicitud

PUT /docs HTTP/1.1
Host: example.com
Content-Type: application/pdf
Content-Length: 10000

<File transfer successful for PDF file>

Respuesta final

HTTP/1.1 200 OK

Cómo solucionarlo

Un 408 Request Timeout significa que el servidor cerró la conexión porque el cliente no completó la solicitud a tiempo.

Compruebe la conectividad y la latencia de la red. Una conexión inestable o lenta retrasa la transmisión de la solicitud. Ejecute ping y traceroute hacia el servidor para identificar pérdida de paquetes o saltos con latencia alta. Confirme que la conexión es estable antes de reintentar.

Reduzca el tamaño de la carga útil o divida las subidas grandes. Enviar un archivo grande por una conexión lenta excede la paciencia del servidor. Comprima la carga útil, use Transfer-Encoding por fragmentos o divida la subida en partes más pequeñas mediante API de subida multiparte.

Aumente los valores de tiempo de espera del lado del cliente. La biblioteca cliente HTTP o el navegador aplican su propio tiempo de espera. Eleve los valores de tiempo de espera de conexión y de lectura para admitir transferencias más lentas. En curl, use —connect-timeout y —max-time. En Python requests, establezca timeout=(connect, read).

Verifique la configuración de tiempos de espera del servidor. Ajuste las directivas de tiempo de espera según el servidor web:

nginx:

client_header_timeout 60s;
client_body_timeout 60s;
keepalive_timeout 75s;
send_timeout 60s;

Apache:

Timeout 60
KeepAliveTimeout 5
RequestReadTimeout header=20-40 body=20

La directiva RequestReadTimeout (mod_reqtimeout) controla por separado los tiempos de espera de lectura de la cabecera y del cuerpo. Aumente estos valores cuando los clientes necesiten legítimamente más tiempo.

Ajuste la configuración de Keep-Alive. Un keepalive_timeout bajo cierra las conexiones inactivas antes de que el cliente envíe la siguiente solicitud en una conexión persistente. En nginx, el valor predeterminado de keepalive_timeout es de 75 segundos. Eleve el valor para API que atienden a clientes con patrones de solicitud a ráfagas. En Apache, aumente KeepAliveTimeout (5 segundos de forma predeterminada) y verifique que MaxKeepAliveRequests permita suficientes solicitudes por conexión.

Revise los tiempos de espera del proxy inverso y del equilibrador de carga. Cuando un proxy inverso (nginx, HAProxy, AWS ELB) se sitúa delante del servidor de aplicaciones, cada capa aplica su propio tiempo de espera. El proxy cierra la conexión primero si su tiempo de espera es más corto que el del backend. En nginx en modo proxy inverso:

proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;

AWS ALB tiene un tiempo de espera de inactividad predeterminado de 60 segundos, configurable en los atributos del equilibrador de carga.

Reintente la solicitud. Un 408 suele ser transitorio. Restablezca la conexión y vuelva a enviar la solicitud completa. Implemente lógica de reintento automático con retroceso exponencial para los clientes programáticos. La cabecera Retry-After, cuando está presente, indica cuánto hay que esperar antes de reintentar.

Revise los registros de errores del servidor. nginx registra los eventos de tiempo de espera en el registro de errores. Apache registra las infracciones de mod_reqtimeout. Consulte /var/log/nginx/error.log o /var/log/apache2/error.log en busca de entradas que coincidan con la marca de tiempo de la solicitud para identificar si el tiempo de espera se agotó al leer la cabecera o el cuerpo.

Referencias de código

.NET

HttpStatusCode.RequestTimeout

Rust

http::StatusCode::REQUEST_TIMEOUT

Rails

:request_timeout

Go

http.StatusRequestTimeout

Symfony

Response::HTTP_REQUEST_TIMEOUT

Python3.5+

http.HTTPStatus.REQUEST_TIMEOUT

Java

java.net.HttpURLConnection.HTTP_CLIENT_TIMEOUT

Apache HttpComponents Core

org.apache.hc.core5.http.HttpStatus.SC_REQUEST_TIMEOUT

Angular

@angular/common/http/HttpStatusCode.RequestTimeout