Tag Archives: http keepalive

HAProxy and HTTP errors 408 in Chrome

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.

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

Related Links


Implement HTTP keepalive without killing your apache server


This howto will explain you how you can use your Aloha LoadBalancer to implement HTTP Keepalive and save resources on your server at the same time.

What is HTTP KeepAlive?

In early version of HTTP protocol, clients used to send request over a new TCP connection to the server, getting content from the server through this connection and finally close it.
This method works well when web pages have a few objects.
More objects means more time to wait for each TCP connection setup and close.

HTTP 1.0 introduced the header Connection: Keepalive.
Clients and servers sent each other this header in order to tell the other side to keep the connection opened.
By default, there was no keepalive.

HTTP 1.1 considers every connection to be kept alive.
If one doesn’t want the connection to stay opened, the client or the server has to send the header: Connection: Close.

By using HTTP Keepalive, you’re going to reduce the web pages load time.
On the other hand, too many TCP connections maintained opened on an Apache server can make it consumes too much memory and CPU.

Using HAProxy to implement HTTP Keepalive

You can use HAProxy to add HTTP keepalive on the client side while not doing it on the server side.
The purpose is to deliver the objects quickly to the client without the overhead of TCP handcheck latency and to release memory and CPU on the server side by releasing TCP connection.
Note: Since HAProxy and the server are on the same LAN, the overhead of latency is negligible.

You can enable HTTP Keepalive on the client side by enabling option http-server-close

frontend public
	bind :80
	option http-server-close
	default_backend apache

backend apache
	option http-server-close
	server srv

PS: Indeed it works for other HTTP server software like IIS, Tomcat, etc….