Lately, there was some discussions on HAProxy’s mailing list about 408 errors printed in Chrome browsers.
Origin of 408 errors
408 is the status code used by web servers or proxies when the client has not sent a whole HTTP request during a certain period of time. It is an absolutely normal behavior!
That said, modern browsers have now some advanced features like « tcp pre-connect »…
As its name designate it, a browser may open tcp connection to web servers before you want to browse them. Purpose is to speed up browsing for the client by saving the time to establish these connections.
The problem, is that in most of the case, these connections won’t be used.
The other problem a very popular website can maintain thousands (or even tens or hundred of thousands) of connections that might be used.
It has an expensive cost on the server side for a so small positive effect on the client side.
When a web server or a proxy accept an incoming connection, in expects a request to come in the next few seconds. If a full request has not arrived after some time, the server or the proxy can close the connection and report a 408 error to the client, to tell him « you were to slow to send me a request on this connection, so I closed it ».
Unfortunately, some browsers, when they want to start using the connection mentioned above, see that data is already available for reading and print it to the user without even checking the connection state (server closing it) neither the response status code (408 in this case).
HAProxy’s timeout related to 408 errors
In HAProxy’s configuration, there are two parameters that may trigger a 408 error:
timeout http-request 10s timeout client 20s
The timeout http-request is the time you let to a client to send it’s request.
If it is not set, then the timeout client will be used.
If both of them are configured, the shortest value is used.
In a default configuration, when answering with a 408, HAProxy sends a message such as this one:
HTTP/1.0 408 Request Time-out Cache-Control: no-cache Connection: close Content-Type: text/html <html><body><h1>408 Request Time-out</h1> Your browser didn't send a complete request in time. </body></html>
This message is printed by some browsers.
Workaround in HAProxy
One way to workaround this issue with HAProxy is to tell HAProxy to silently close the connection without sending any data.
You can add the line below in your defaults (or frontend/listen) section:
errorfile 408 /dev/null
Bear in mind this is just a workaround and not a definitive solution