HAProxy后端宕机时出现HTTPS重定向循环的问题咨询
Great question! Let's break down exactly why this HTTPS redirect loop pops up when your backends are down, and how to fix it while keeping your HTTP-to-HTTPS redirects intact.
What's Causing the Loop?
The core issue boils down to how HAProxy handles error responses when all backend nodes are offline, combined with your redirect rules. Here's the most common scenario:
- You've got a standard rule to redirect all HTTP (port 80) traffic to HTTPS (port 443) — this works fine when backends are healthy.
- To make error pages consistent across protocols, you probably added an
errorloc 503rule (or similar) that tells HAProxy to redirect 503 errors to the HTTPS version of the same URL. - When all backends for a site go down, an HTTPS request comes in: HAProxy can't route it to a backend, so it triggers the 503 error. If your
errorlocrule doesn't check whether the original request was already HTTPS, HAProxy will send a 301 redirect back to the same HTTPS URL. The browser repeats the request, HAProxy hits the same 503/redirect cycle, and you're stuck in a loop.
Another less likely (but possible) scenario is if you're binding both 80 and 443 to the same frontend and have a misconfigured redirect condition — but since you said things work when backends are up, this is far less probable.
How to Fix It
You need to split your error handling logic to treat HTTP and HTTPS requests differently, so HTTPS requests don't get redirected to themselves when backends are down. Here are two solid solutions:
Option 1: Use Local Error Pages for HTTPS
Keep your HTTP-to-HTTPS redirects, but replace the cross-protocol errorloc rule for HTTPS with a local static 503 page:
# In your HTTPS frontend frontend https_frontend bind *:443 ssl crt /path/to/your/certs/ # Your existing host ACLs and backend routing rules acl host_foo hdr(host) -i foo.example.com acl host_bar hdr(host) -i bar.example.com use_backend foo_backend if host_foo use_backend bar_backend if host_bar # Serve a local 503 page for HTTPS requests when backends are down errorfile 503 /etc/haproxy/errors/503-custom.http
For HTTP traffic, you can still redirect 503s to HTTPS if you want:
# In your HTTP frontend frontend http_frontend bind *:80 # Normal HTTP-to-HTTPS redirect for all healthy requests redirect scheme https code 301 if !{ ssl_fc } # Redirect HTTP 503 errors to HTTPS errorloc 503 https://%[hdr(host)]%[req.url]
Option 2: Conditional Error Redirects
If you want to keep a single frontend for both protocols, add a condition to your errorloc rule so it only redirects non-HTTPS requests:
frontend combined_frontend bind *:80 bind *:443 ssl crt /path/to/your/certs/ # Normal HTTP-to-HTTPS redirect redirect scheme https code 301 if !{ ssl_fc } # Your host ACLs and backend rules acl host_foo hdr(host) -i foo.example.com acl host_bar hdr(host) -i bar.example.com use_backend foo_backend if host_foo use_backend bar_backend if host_bar # Only redirect 503s to HTTPS if the original request was HTTP errorloc 503 https://%[hdr(host)]%[req.url] if !{ ssl_fc } # Serve local 503 for HTTPS requests errorfile 503 /etc/haproxy/errors/503-custom.http if { ssl_fc }
How to Verify
After updating your config and restarting HAProxy:
- Take all backend nodes offline for one site (e.g., foo).
- Visit
https://foo.example.com— you should see your custom 503 page immediately, no redirects. - Visit
http://foo.example.com— you'll be redirected to HTTPS, then see the 503 page.
This keeps your HTTP-to-HTTPS redirects working while eliminating the loop when backends fail.
内容的提问来源于stack exchange,提问作者tvlooy

