Custom Error and Maintenance Pages for Nginx and Apache

Use Custom Error Pages For Your Maintenance and Down Time

- Chris Pook, 21st November 2017

Ensure you promote a customer facing message even during maintenance or unexpected down time


In the modern era of e-commerce, a site outage can have a serious monetary loss associated; not to mention putting a dent in your brand and customer's trust.

Site outages can happen for any number of reasons, from scheduled maintenance to unexpected errors out of your control. The method below provides a clean way to mitigate these potential losses by still serving the end user a functional web page explaining the situation and even offering a call to action to retain the engagement.

Usually the cause of a site outage comes from a low level application error. There are an infinite number of ways this can happen, for instance a failed deploy; deployment of untested bad code; failure of a third-party service or plain old lack of server resources. So next time you encounter a disk full scenario or the database goes offline, ensure your site stays "up" with the following instructions for Nginx and Apache.

Nginx Custom Error Config

By adding the following to your site's Nginx virtual host configuration, a custom page may be displayed for any given error code. Without this in place your users will be met with the standard Nginx error page, or worse potentially a stream of error output from your application. On a standard setup you should find the virtual host to add this config in the /etc/nginx/sites/enabled directory, although this may vary dependent on setup.

server {
    ...
    fastcgi_intercept_errors on;
    error_page 500 501 502 503 504 /error-50x.html;
    set $error_root $document_root;

    location ~ ^/error-.*$ {
        internal;
        root $error_root/errors;
    }
}

To break this down

fastcgi_intercept_errors on;

This line is required to tell Nginx that response codes greater than or equal to 300 should be redirected to Nginx for processing with the error_page directive.

Nginx cfastcgi_intercept_errors documentation

error_page 500 501 502 503 504 /error-50x.html;

The error_page directive specifies the actual page you wish the user to be served with for a given HTTP response code. You may add multiple error_page directives to specify separate pages for each code or group them to a generic page as above. Be aware that the page the user is met with should not rely on any dynamic content, as the site is down you are looking to inform the user of the situation and if possible capture their data, see below for ideas for this.

Nginx error_page documentation

set $error_root $document_root;

This line is required to facilitate the section below which specifies where the error pages are on the server. As the Nginx root directive cannot use the $document_root variable directly, this just makes a copy of it's value which can be used.

location ~ ^/error-.*$ {
    internal;
    root $error_root/errors;
}

Finally this block specifies that for any page request fitting the the error-* pattern, look in the web root errors directory. You may want to use different naming here if there is any likelihood your application has URLs beginning with 'error-'. This URL wont be visible to the user so it can be named whatever you want. The error page content will show on the URL the user requested.

Apache Custom Error Config

Apache web server has the exact same functionality available as Nginx with the following config added to your virtual host:

ErrorDocument 500 /errors/error-50x.html
ErrorDocument 502 /errors/error-50x.html
ErrorDocument 503 /errors/error-50x.html
ErrorDocument 504 /errors/error-50x.html

This simply specifies the page to load upon encountering the relevant HTTP codes.

Apache ErrorDocument documentation

So with the above server configuration in place you are now covered for any 50x application error. You can also at any time reliably put your application in to maintenance mode (returning a 503 "Service unavailable" response) and the site will serve your custom content until the service comes back up.

The errors directory is in your web root folder so can be managed as part of your application version control. One other thing to note is that any assets such as images you render on the error page will load relative to the root directory, not the errors directory. Always test your error page after setup, ideally in a UAT environment.


What To Put On Your Error Page ?

We suggest keeping the content of your error page simple and to the point. Offer the user an explanation for why they can't access what they were expecting. Something along the lines of "Please bear with us during a period of maintenance".

Ensure you don't include anything on the page which relies on services that may be the cause of the outage (PHP, databases etc). If you did want to add dynamic content you can obviously still use javascript and action things on the front-end. This might include submitting a form via javascript to capture email addresses in an external system for which you can later send out an apology and potentially a good will discount code.


Handling 404 Page Not Found

This exact same mechanism can be used to load a custom 404 page if your application is not already doing so. This is much better for user experience than just serving a blank server error page, we'd suggest linking to your best content from here.

Nginx Custom 404 Config

error_page 404 /error-404.html;

Apache Custom 404 Config

ErrorDocument 404 /errors/error-404.html

Don't forget to add the custom page to your errors directory so that it is there to serve.