sfw/fix
408 medium

408 Request Timeout

The server stopped waiting for the client to finish sending the request and closed it with a 408.

What you see

408 Request Timeout
The server timed out waiting for the request.

What’s actually happening

A 408 shows up on slow uploads, on flaky mobile connections, or seemingly at random in the access log on otherwise idle keep-alive connections. It's the mirror image of a 504: here the server is waiting on the client, not the other way around. Browsers sometimes silently retry a 408, so users may not even notice, while your logs fill up with them.

Common causes

  • A client uploading a large file or posting a big form over a slow link, taking longer than the server's request-read timeout.
  • Idle keep-alive connections being reaped — many 408s in the log are just Nginx/Apache closing connections that opened but sent nothing, which is normal noise.
  • An aggressive timeout: Apache 'RequestReadTimeout' or 'Timeout', or Nginx 'client_body_timeout' / 'client_header_timeout' set too low for real-world clients.
  • A reverse proxy or load balancer between client and origin with its own short request timeout (some send 408, some 504).
  • A client that opens a connection and stalls — sometimes a buggy script, sometimes a slowloris-style probe sending bytes very slowly.

How to fix it

  1. Decide whether the 408s are noise or realGrep the access log for 408 and look at the request line and user agent. Lots of '"-" 408' with empty requests on keep-alive are harmless connection reaping. 408s on real POST/upload URLs with real clients are the ones worth fixing.
  2. Loosen the read timeouts for legitimate slow clientsIn Nginx raise 'client_body_timeout' and 'client_header_timeout' (e.g. 60s) and 'client_max_body_size' for big uploads. In Apache adjust 'RequestReadTimeout body=...' and 'Timeout'. Reload and retest a slow upload.
  3. Push large uploads to chunked/resumable transferFor genuinely big files, switch the client to chunked or resumable uploads (tus, multipart with retries) so a slow link doesn't have to finish one long request inside the timeout window.
  4. Keep slowloris protection without nuking real usersIf the 408s are slow-byte probes, that's the read timeout doing its job. Pair it with rate limiting or mod_reqtimeout tuned to your real upload speeds, rather than setting the timeout so tight that mobile users on a bad connection get cut off.

Stop it recurring

Set request-read timeouts generous enough for your slowest legitimate upload, and treat empty keep-alive 408s as expected log noise rather than a bug to chase.

Related errors