408 Request Timeout: what it means and how to fix it

·4 min read

A 408 Request Timeout means the server stopped waiting for the client to finish sending its request. The 408 code blames the client's side of the connection, usually a slow upload, a stalled mobile connection, an idle keep-alive connection the server chose to close, or a server read timeout set too low.

Most 408s are log noise. They matter when real users or Googlebot get them on pages that should load.

What does a 408 request timeout mean?

RFC 9110 defines 408 as a server that "did not receive a complete request message within the time that it was prepared to wait" (section 15.5.9). The server never started on a response. It was still reading headers or body when its timer ran out. The same section lets the client repeat the request on a new connection, and browsers often do, which is why visitors rarely see a 408 page.

MDN explains most of the 408 lines you will find. Some servers send a 408 on an idle connection even when no request arrived, and Chrome and Firefox open such connections early to speed up browsing (MDN on 408). The browser preconnects, never uses the socket, and the server logs a 408 as it closes it.

408 vs 504 gateway timeout

A 408 means the client was too slow to send the request. A 504 means a gateway or proxy did not get "a timely response from an upstream server" (RFC 9110, section 15.6.5).

408 Request Timeout 504 Gateway Timeout
Class 4xx client error 5xx server error
Who was slow The client sending the request The app behind the proxy
When the timer fires While the server reads headers or body After the request went upstream
Where to look Upload size, client network, read timeouts Slow queries, upstream timeouts, app logs

A page that takes 70 seconds to render gets a 504 from the proxy, never a 408. For the other proxy errors, see our guide to the 502 Bad Gateway error.

Common causes of a 408 code

Idle connections. The server closes a keep-alive or preconnected socket that sat unused and logs a 408. Apache logs these with a request line of "-".

Slow uploads. A large form post over a weak connection stalls, and the body read timeout fires. nginx returns 408 when the client sends nothing for client_body_timeout, 60 seconds by default (nginx core module docs).

Read timeouts set too low. Every server sends a 408 when its read limits expire.

Server Setting Default
nginx client_header_timeout, client_body_timeout 60s each
Apache RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
Node.js server.headersTimeout, server.requestTimeout 60s, 300s

The Apache and Node values come from the mod_reqtimeout docs and the Node.js HTTP docs. Cut them to a few seconds to stop slow-client attacks and mobile users start getting 408s.

How does Google treat a 408?

Google treats a 408 like any 4xx other than 429. Its page on how HTTP status codes affect its crawlers says Google doesn't use content from 4xx URLs, doesn't index them and drops indexed URLs that start returning 4xx. It also says 4xx codes other than 429 don't change crawl rate. It never names 408.

So a 408 won't slow Googlebot the way a 5xx does, but a URL that keeps returning it can leave the index. Googlebot's page fetches are GET requests without a body, so upload size is rarely the cause. Look for a very short header timeout, a proxy or firewall holding connections, or a server too loaded to read requests in time. Our guide to HTTP status codes for SEO compares the other 4xx codes.

How to fix a 408 request timeout

  1. Filter your access log for 408. Lines with a request of "-" are idle connections closing. Ignore them.
  2. Group the rest by path. Upload endpoints point to body timeouts. Ordinary pages point to header timeouts or an overloaded server.
  3. Compare your read timeouts with the defaults above. If someone set them to 5 or 10 seconds, raise them.
  4. Send large uploads in chunks or straight to object storage, so no single request body takes minutes.
  5. Check the CDN, load balancer or WAF in front of you. It can return its own 408 before your server sees the request.

In nginx, set the read timeouts in the server block:

server {
    client_header_timeout 60s;
    client_body_timeout 60s;
    client_max_body_size 50m;
}

Don't raise them past a few minutes to hide the problem. Long read timeouts let slow clients hold connections open, the very attack these settings exist to stop.

Check your URLs for 408 errors in bulk

Our HTTP Status Bulk Checker takes up to 20 pasted URLs, one per line, and requests each. It returns every URL's status code, first redirect and target, final URL, hop count and response time, and counts the 4xx, 5xx, redirects and unreachable URLs. A 408 lands in the 4xx count. Each URL gets 8 seconds and up to five redirects, and one that doesn't answer in time is marked unreachable.

It doesn't download page bodies, crawl your site or read your logs, so it shows what a URL returns now, not how often it failed last week. A run costs 20 credits.

Keep reading