HAProxy Health Check Configuration for Multiple Servers with Different Host Headers


4 views

When load balancing across servers with different hostnames, HAProxy's default health check behavior can cause issues since it uses the server's address rather than the application's virtual host. The http-send-name-header Host directive doesn't apply to health checks in HAProxy 1.5, requiring workarounds.

Here's the core challenge: We want a single listen section while maintaining proper host header validation during health checks. The key components needed:

option httpchk HEAD / HTTP/1.1\r\nHost: example.com
http-send-name-header Host

For HAProxy 1.5, we need separate listen blocks for each server when different host headers are required. Here's an optimized version:

global
    log 127.0.0.1 local0 notice
    maxconn 2000
    user haproxy
    group haproxy

defaults
    log     global
    mode    http
    option  httplog
    option  dontlognull
    retries 3
    option redispatch
    timeout connect  5000
    timeout client  10000
    timeout server  10000
    stats enable
    stats uri /haproxy?stats
    stats refresh 5s
    balance roundrobin
    option httpclose

frontend main
    bind *:80
    use_backend bk_app1 if { hdr(host) -i www.example.com }
    use_backend bk_app2 if { hdr(host) -i www.bing.com }

backend bk_app1
    option httpchk HEAD / HTTP/1.1\r\nHost:\ www.example.com
    server s1 127.0.0.101:80 check

backend bk_app2
    option httpchk HEAD / HTTP/1.1\r\nHost:\ www.bing.com
    server s2 127.0.0.102:80 check

For newer HAProxy versions (1.6+), you can use more elegant solutions:

backend servers
    option httpchk
    http-check send meth HEAD uri / hdr Host example.com
    server s1 127.0.0.101:80 check
    server s2 127.0.0.102:80 check hdr Host bing.com
  • Health check intervals should match application requirements
  • Different rise/fall thresholds per backend if needed
  • SSL termination adds complexity to host header handling
  • Consider using ACLs for more complex routing logic

When load balancing across multiple backend servers that each have different hostnames (and where you can't configure identical virtual hosts), HAProxy's health check mechanism requires special consideration. The core issue is that standard HTTP health checks won't properly validate servers that require specific Host headers.

While http-send-name-header Host works for regular traffic forwarding, it doesn't automatically apply to health checks. In HAProxy 1.5 (and even in newer versions), health checks need explicit Host header configuration.

Here's an optimized approach that maintains clean configuration while properly handling health checks:

global
    log 127.0.0.1 local0 notice
    maxconn 2000
    user haproxy
    group haproxy

defaults
    log     global
    mode    http
    option  httplog
    option  dontlognull
    retries 3
    option redispatch
    timeout connect  5000
    timeout client  10000
    timeout server  10000
    stats enable
    stats uri /haproxy?stats
    stats refresh 5s
    balance roundrobin
    option httpclose

listen inbound :80
    option httpchk
    server instance1 127.0.0.101 check inter 3000 fall 1 rise 1
    server instance2 127.0.0.102 check inter 3000 fall 1 rise 1

backend instance1_backend
    option forwardfor
    http-send-name-header Host
    option httpchk HEAD / HTTP/1.1\r\nHost:\ www.example.com
    server www.example.com www.example.com:80 check inter 5000 fall 3 rise 2

backend instance2_backend
    option forwardfor
    http-send-name-header Host
    option httpchk HEAD / HTTP/1.1\r\nHost:\ www.bing.com
    server www.bing.com www.bing.com:80 check inter 5000 fall 3 rise 2

1. Using backend sections instead of multiple listen blocks for cleaner organization
2. Explicit Host headers in health checks for each backend
3. Maintaining separate check intervals and thresholds based on server requirements

If you can upgrade to HAProxy 1.6 or later, you can use the http-check send directive for more flexibility:

backend example_backend
    option forwardfor
    http-send-name-header Host
    http-check send meth HEAD uri / hdr Host www.example.com
    server www.example.com www.example.com:80 check inter 5000 fall 3 rise 2

After implementing this configuration, verify your health checks are working properly by:
- Checking HAProxy stats page
- Examining logs for health check failures
- Using curl -I to manually test backend responses