Skip to content

HTTP status code · Client errors (4xx)

408 Request Timeout

408 Request Timeout means the server did not receive the complete request within the time it was willing to wait, so it gave up. The slowness is on the sending side: a slow or stalled upload, a flaky connection, or a connection opened and left idle.

Facts about this status code
Class4xx, Client errors
Defined inRFC 9110 §15.5.9
Cacheable by defaultOnly with explicit Cache-Control or Expires
Safe to retryYes, the client may resend the request, on a new connection if needed
Relevant headers
  • Connection: servers usually send Connection: close with a 408 and drop the connection

What 408 means

RFC 9110, section 15.5.9, defines 408 as the server not receiving a complete request message in time. It explicitly allows the client to repeat a request that was in transit, on a new connection if the current one is no longer usable. That makes 408 one of the few 4xx codes where retrying the same request is expected.

Do not confuse it with a slow application. If the request arrived and your code took too long, that is a 504 from a gateway or a client-side timeout, not a 408. Node.js sends 408 on its own when a request exceeds server.requestTimeout (300 seconds by default) or its headers exceed headersTimeout, and nginx ends requests with 408 when client_header_timeout or client_body_timeout expire (60 seconds each by default).

Some 408s in access logs are harmless: browsers open spare connections in advance to speed up later navigation, and when no request ever arrives, some servers log the idle connection as a 408.

Common causes

If you are visiting the site

  • A slow, unstable or congested connection (mobile data, overloaded Wi-Fi) while submitting a form or uploading a file.
  • The computer went to sleep or the network changed in the middle of an upload.

If you run the server

  • Client body or header timeouts that are too short for large uploads over slow links.
  • A client that sets Content-Length larger than the body it actually sends, so the server waits for bytes that never come.
  • Speculative or keep-alive connections that stay open without a request and hit the server timeout.

How to fix it

If you are visiting the site

  • Reload and submit again, ideally on a steadier connection.
  • For large files, retry on Wi-Fi or compress the file first.

If you run the server

  • Raise client_body_timeout in nginx or requestTimeout in Node for upload endpoints, or move uploads to direct-to-storage presigned URLs.
  • Make clients retry idempotent requests on 408 with a new connection; many HTTP libraries already do this.
  • Check that the Content-Length your client sends matches the body, especially when a proxy rewrites or compresses it.
  • Ignore 408 log entries with no request line; they are idle preconnects, not failed users.

How to send 408

You rarely write a 408 by hand: the HTTP server sends it when its read timeouts expire, so configure those timeouts instead.

Express (Node.js)
const server = app.listen(3000);
// Node answers 408 itself when these expire
server.headersTimeout = 10_000; // headers must arrive within 10 s
server.requestTimeout = 60_000; // whole request within 60 s
Nginx
server {
  # nginx ends the request with 408 when these expire
  client_header_timeout 10s;
  client_body_timeout 60s;
}

Commonly confused with

408 vs 504
504 means a gateway waited too long for the upstream server; 408 means the server waited too long for the client.
408 vs 499
499 is nginx logging that the client gave up first; 408 is the server giving up on the client.
408 vs 524
524 is Cloudflare timing out while waiting for your origin to answer, which is the opposite direction of a 408.

Frequently asked questions

Is a 408 error caused by the client or the server?
The server reports that the client was too slow to send the request. The fix is a better connection, a smaller payload, or longer timeouts on the server for legitimate slow uploads.
Can I retry a request after 408?
Yes. RFC 9110 allows the client to repeat the request, on a new connection if the old one is closed. For non-idempotent requests such as payments, make sure the server did not already process it, for example with an idempotency key.
Why are there so many 408s in my access log?
Often they come from connections browsers open ahead of time and never use. When the server times out an idle connection that carried no request, some servers log it as 408. They do not affect users.

Last reviewed by Arielton Oberek.