How to set up a fallback error page in nginx?

Solution 1:

I ended up going with something a lot closer to my original idea. The key I was missing turned out to be the directive recursive_error_pages. All I really had to do was turn this "on" and my original idea worked. Here's what the relevant part of my conf looks like now:

server {
    ...

    root /var/www/someserver.com/;

    error_page 400 404      /404.html;
    error_page 500 502 504  /500.html;
    error_page 503          /503.html;

    recursive_error_pages   on;

    location ~* ^/(404\.html|500\.html|503\.html)$ {
        log_not_found off;
        error_page 404 = @default;
    }

    location @default {
        log_not_found on;
        root /var/www/default;
    }
}

I included other error types that were not part of my original question here because this is what ended up causing me difficulties with Martin F's approach, which was otherwise excellent. The log_not_found directive just ensures that I don't get 404s in my log when the error page isn't found in the original root.

Solution 2:

try_files is the way to go here. The following configuration should work, but I haven't tested it for syntax errors.

server {
    ...
    root /var/www;

    location / {
        try_files /someserver.com$uri /default$uri /someserver.com$uri/ /default$uri/ @notfound;
    }

    location @notfound {
       try_files /someserver/404.html /default/404.html =404; # =404 should make it use the nginx-default 404 page.
    }
}

Solution 3:

Unfortunately I'm a couple years late with my answer, but I thought it might help the future searchers. My installed Nginx version is 1.2.4, and I've created the following configuration snippet,

server {

server_name www.example.com
root /var/www/example


## Errors -> Locations
error_page   400 /400.html;
error_page   403 /403.html;
error_page   404 /404.html;
error_page   500 502 503 504 /50x.html;

## Locations -> Fallback
location = /400.html {
    try_files /400.html @error;
    internal;
}
location = /403.html {
    try_files /403.html @error;
    internal;
}
location = /404.html {
    try_files /404.html @error;
    internal;
}
location = /50x.html {
    try_files /50x.html @error;
    internal;
}

## Fallback Directory
location @error {
    root /var/www/error;
}

}