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 absolutely normal behavior!
That said, modern browsers now have some advanced features like “tcp pre-connect”, as its name designates, a browser may open a 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 cases, these connections won’t be used.
The other problem is that a very popular website can maintain thousands (or even tens or hundred of thousands) of connections that might be used. It is an expensive cost on the server side for a small positive effect on the client side.
When a web server or a proxy accepts an incoming connection, it 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 too 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) nor 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 a client send its 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