When HAProxy encounters a server returning HTTP 503 (Service Unavailable), it typically passes this response directly to the client. Unlike some other proxies, HAProxy doesn't natively generate its own 503 pages unless it's handling the error internally (like during maintenance mode).
We can implement a custom 503 page by using HAProxy's errorfile
directive combined with backend health check monitoring. Here's the complete approach:
frontend http_front
bind *:80
default_backend web_servers
backend web_servers
option httpchk GET /health
http-check expect status 200
server server1 192.168.1.10:80 check
server server2 192.168.1.11:80 check backup
# Custom error document
errorfile 503 /etc/haproxy/errors/503.http
Create a file at /etc/haproxy/errors/503.http
with this format:
HTTP/1.0 503 Service Unavailable
Cache-Control: no-cache
Connection: close
Content-Type: text/html
<!DOCTYPE html>
<html>
<head>
<title>Service Temporarily Unavailable</title>
</head>
<body>
<h1>503 Service Unavailable</h1>
<p>Our servers are currently overloaded. Please try again later.</p>
</body>
</html>
For more control over when the custom page appears, consider these additional directives:
backend web_servers
# Return custom 503 when all servers are down
errorfile 503 /etc/haproxy/errors/503.http
# Or use this alternative for more granular control
http-request return status 503 content-type text/html lf-string %[var(txn.custom_503)] if { nbsrv eq 0 }
# Set the custom response content
http-request set-var(txn.custom_503) str("<html>...custom content...</html>") if { nbsrv eq 0 }
After implementing, test with:
curl -v http://your-haproxy-ip/
When all backend servers are down, you should receive your custom 503 page instead of the default response.
Remember that HAProxy will serve this error page from memory once loaded, so keep the file size reasonable. For very large error pages, consider using the http-response return
method with external file includes.
When backend servers fail in HAProxy, by default users receive a barebones 503 Service Unavailable error. This creates poor user experience and missed branding opportunities. A properly configured custom error page helps maintain professionalism during outages.
HAProxy provides the errorfile
directive to handle custom error pages. For 503 errors, the configuration goes in either the global or frontend section:
frontend main bind *:80 errorfile 503 /etc/haproxy/errors/503.http default_backend app_servers
The error file must follow HTTP protocol format. Create /etc/haproxy/errors/503.http
with:
HTTP/1.0 503 Service Unavailable Cache-Control: no-cache Connection: close Content-Type: text/html <!DOCTYPE html> <html> <head> <title>Maintenance in Progress</title> </head> <body> <h1>We'll Be Back Soon!</h1> <p>Our services are temporarily unavailable.</p> </body> </html>
For dynamic content, use errorloc
to redirect to an external URL:
frontend main bind *:80 errorloc 503 https://status.yourdomain.com
Verify configuration and test using these commands:
haproxy -c -f /etc/haproxy/haproxy.cfg curl -v http://yourhaproxy:80
When backend servers are down, you should now see your custom error page instead of the default response.
- Ensure HAProxy has read permissions on the error file
- Verify the error file contains proper HTTP headers
- Check for typos in the file path
- Test with multiple browsers