Custom Bad Gateway Page with Nginx

Nginx

Nginx Problem Overview


Is it possible to serve a custom "Bad Gateway" error page in Nginx?

Similar to having custom 404 pages.

Nginx Solutions


Solution 1 - Nginx

There are three pieces that must be in place in order for your custom error page to display instead of the generic "Bad Gateway" error.

  1. You must create an html file named something like "500.html" and place it in the root. In the case of Rails running behind Nginx, this means putting it at public/500.html.

  2. You must have a line in your config file that points at least the 502 errors to that 500.html page like this:

     error_page 502 /500.html;
    
  3. You must have a location block for /500.html in your config file. If your root is already defined, this block can be empty. But the block must exist nonetheless.

     location /500.html{
     }
    

Solution 2 - Nginx

It's similar to setting up the custom 404 pages. Here's what I've got.

#site-wide error pages
error_page 404 /404.html;
error_page 500 502 503 504 /500.html;

Solution 3 - Nginx

using debian (9.3 stretch actually) i did following steps:

  • create /var/www/html/502.html with the content for the 502 error page

  • edit /etc/nginx/sites-enabled/mywebsite.conf

so it looks similar like this:

server {
    listen 80; listen [::]:80;
    server_name www.mywebsite.com;

    error_page 502 /502.html;
    location /502.html {
        root /var/www/html;
    }
}
  • then restarted nginx using service nginx restart

Solution 4 - Nginx

While @Larsenal's answer is technically correct for the minimum configuration, there are common configurations that will make it not work. @Jack Desert's answer touches on this but doesn't provide a full explanation of why that's needed.

Suppose we have this configuration (simplified from @Jack).

error_page 502 504 /my-error-page.html;

What this is saying is, in the case of a 502 or 504 error internally, rewrite the original URI as /my-error-page.html.

What I think most people miss is that this then goes through the same processing chain that happens as if you requested that page directly. This means that it goes through all the same location block checks.

Since a common method of doing a reverse proxy on nginx is to configure a location / { block, that location matches /my-error-page.html and thus nginx tries to use the proxy to serve the error file. Since a common use case is serving a static file in the case that the backend is down, serving this error page from the backend will likely also fail, making nginx default to serving its own internal error page that we were trying to replace in the first place.

So, a common solution, the one @Jack Desert suggests, is to include another location block that will match the /my-error-page.html URL before the location / block. Note that the order of location blocks in nginx configuration has no effect; There is a very specific set of rules for picking precedence of location blocks based on the URL. That location block needs to have whatever is necessary to serve that file like any other static file that nginx might serve. This means a root directive is needed somewhere and that /my-error-page.html will be loaded relative to that (root can be set at nearly any level of the nginx configuration).

Solution 5 - Nginx

Yes it is possible

Type this in your terminal

cd /etc/nginx

sudo nano nginx.conf

and under http add these lines

    error_page 500 Path_to_your_custom_error_page;
    error_page 503 Path_to_your_custom_error_page;
    error_page 504 Path_to_your_custom_error_page;

Now restart nginx by typing this command:

sudo service nginx restart

Bingo now you can see custom error message on gateway error

Solution 6 - Nginx

The question doesn't say, but it's quite common to hit this problem when API's are behind an nginx pass through proxy, so in that case you want the response to be JSON not HTML.

My favorite approach is to just use the redirect functionality of the error_page directive to redirect back to an error page on the same site:

error_page 502 503 $scheme://$server_name/500.json;

It's one line, you can reuse the same 500.json for different location's, and there is no need for a mysterious empty location. You place your error message in the 500.json file at the root of your site. I assume that you already have a location / {...} directive there that serves up static files.

You can of course use this same approach to serve an HTML error page too.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondebView Question on Stackoverflow
Solution 1 - NginxJack DesertView Answer on Stackoverflow
Solution 2 - NginxLarsenalView Answer on Stackoverflow
Solution 3 - NginxChristoph LöschView Answer on Stackoverflow
Solution 4 - NginxCameron TacklindView Answer on Stackoverflow
Solution 5 - NginxSachin JaiswalView Answer on Stackoverflow
Solution 6 - NginxjlyonsmithView Answer on Stackoverflow