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
forHAProxy
. You will have to add a one line configuration underglobal
section to enable this.global stats socket /var/run/haproxy.sock mode 600 level admin
Official documentation