Nginx – error_page doesn’t seem to work with nginx upstream directive

failoverload balancingnginx

I am trying to use nginx to load-balance a couple of downstream app servers, and to show a "fail whale" style page if all the downstream servers are offline or unresponsive. Unfortunately, the nginx documentation says that you can't use the backup directive in combination with the ip_hash directive in an upstream block, so I have been trying to come up with an alternative.

Right now, the relevant blocks in my config are:

upstream appservers {
    ip_hash;
    server srv1:8080;
    server srv2:8080;
}

server {
    listen       80;

    location / {
        proxy_pass http://appservers;
        proxy_set_header X-Scheme $scheme;
        proxy_connect_timeout 5s;
        error_page   502 503 504  http://failwhale.myapp.com;
    }
}

The problem is that if I shut down both app servers, when nginx returns a 502 (bad gateway) error it just seems to use the default 502 error page (the plain white-ish one) instead of redirecting to http://failwhale.myapp.com (which is also served by nginx and is definitely up).

Does anyone know what I'm doing wrong, or if this is even supposed to work as I'm hoping? If not, what else can be done?

Best Answer

Figured it out. You need the proxy_next_upstream decl to catch those errors, a la:

location / {
    proxy_pass http://appservers;
    proxy_set_header X-Scheme $scheme;
    proxy_connect_timeout 5s;
    proxy_next_upstream error timeout http_502 http_503 http_504;
    error_page   502 503 504  http://failwhale.myapp.com;
}