HAProxy returns Bad Request (Invalid Host) for seemingly no reason

Solution 1:

I faced the same issue and took me a while to figure out why this was happening.

My environment is formed by 1 HAproxy and 2 nginx as a backend with nodejs as a CGI-like.

The root cause is based on how HAproxy builds the HTTP request. By default HAproxy would not include host header on the request, so you need to added manually, otherwise nginx will return 400 as default and HAproxy will mark it as unhealthy.

Example Below:

  • HAproxy health check conf:

    option httpchk HEAD / HTTP/1.1
    
  • Equivalent HTTP request:

    tony@calderona:~ $ telnet A.B.C.D 80
    Trying A.B.C.D...
    Connected to A.B.C.D.
    Escape character is '^]'.
    HEAD / HTTP/1.1
    
    HTTP/1.1 400 Bad Request
    Server: nginx/1.10.3
    Date: Sun, 10 Dec 2017 09:52:12 GMT
    Content-Type: text/html
    Content-Length: 173
    Connection: close 
    
  • HAproxy health check conf:

    option httpchk HEAD / HTTP/1.1\r\nHost:\ www.temporaryworkaround.org
    
  • Equivalent HTTP request:

    tony@calderona:~ $ telnet A.B.C.D 80
    Trying A.B.C.D...
    Connected to A.B.C.D.
    Escape character is '^]'.
    HEAD / HTTP/1.1
    host: www.temporaryworkaround.org
    
    HTTP/1.1 200 OK
    Server: nginx/1.10.3
    Date: Sun, 10 Dec 2017 09:52:24 GMT
    Content-Type: text/html; charset=utf-8
    Content-Length: 10282
    Connection: keep-alive
    

Cheers

Solution 2:

If you want to see the exact error HAproxy runs into you can do so using socat to connect to the admin socket. Install socat via apt-get install socat, then run the following:

echo "show errors" | socat unix-connect:/run/haproxy/admin.sock stdio

If you run this right after getting a "Bad Request" error it should show you exactly what HAproxy didn't like about the HTTP request the client made.

NOTE: The above works only when you have enabled Unix Socket commands for HAProxy. You will have to add a one line configuration under global section to enable this.

global
     stats socket /var/run/haproxy.sock mode 600 level admin

Official documentation