≡ Menu

NGINX: Create Custom 404 / 403 Error Page

How do I create a custom static HTTP 404 or HTTP 403 error page under nginx web server?

First create 404.html in your document root. The default is location is /usr/local/nginx/html/. So create a HTML file as follows:
# vi /usr/local/nginx/html/404.html
Sample outputs:

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Error 404 Not Found</title>
<style>
<!--
	body {font-family: arial,sans-serif}
	img { border:none; }
//-->
</style>
</head>
<body>
<blockquote>
	<h2>Error 404 Not Found</h2>
	<p>Our apologies for the temporary inconvenience. The requested URL was not found on this server.  We suggest you try one of the links below:
	<ul>
		  <li><b>Verify url and typos</b> - The web page you were attempting to view may not exist or may have moved - try <em>checking the web address for typos</em>.<//li>
		  <li><b>E-mail us</b> - If you followed a link from somewhere, please let us know at <a href="mailto:webmaster@example.com">webmaster@example.com</a>. Tell us where you came from and what you were looking for, and we'll do our best to fix it.</li>
	</ul>
</blockquote>
</body>
</html>
 

Edit /usr/local/nginx/conf/nginx.conf file, enter:
# vi /usr/local/nginx/conf/nginx.conf
Append / edit config as follows:

 
error_page   404  =  /404.html;
 

An example to prevent clients fetching error pages directly:

error_page 404 /404.html;
location  /404.html {
  internal;
}

An example of HTTP 403 error page:

 
error_page 403 /403.html;
       location = /403.html {
           root   html;
           allow all;
       }
 

Save and close the file. Reload nginx, enter:
# /usr/local/nginx/sbin/nginx -t && /usr/local/nginx/sbin/nginx -s reload

Tweet itFacebook itGoogle+ itPDF itFound an error/typo on this page?

{ 12 comments… add one }

  • yoyo August 9, 2011, 8:43 pm

    why in /usr/local?
    I always pack this brilliant piece of software for OS I use.

  • khupcom September 19, 2011, 11:52 pm

    Thanks for the tutorial. I need dynamic 404 page with php example 404.php but looks like nginx ignore php file for 404 page.
    Any help realy appreciate.

  • Phoenix May 16, 2012, 5:14 pm

    Thanks, but this is a highly unclear posting. Where do those lines go — inside the “http” directive, or inside each server block?

    • nixCraft May 16, 2012, 5:27 pm

      Try any one of the following context:

      1. http
      2. server
      3. location
      4. if in location
  • Phoenix May 16, 2012, 5:28 pm

    Thanks Vivek. Can I do outside http?

  • Phoenix May 16, 2012, 5:29 pm

    And what do the permissions of the files have to be — chmod 777?

    • cybernet July 6, 2014, 7:21 am

      644
      files should always have 644 and directories 755

  • Phoenix May 16, 2012, 5:32 pm

    Doesn’t work inside http context, and doesn’t work outside it.

    Shows me this error:

    Restarting nginx daemon: nginxRemaining processes: 12683
    nginx: [emerg] "location" directive is not allowed here in /etc/nginx/nginx.conf:67
    

    Is this only allowed inside location blocks? I’m using 1.0.8.

    • nixCraft May 16, 2012, 6:34 pm

      Here is another example put it in server context:

      server {
            access_log  logs/example.com/access.log main;
            error_log   logs/example.com/error.log;
            index       index.html;
            root        /usr/local/nginx/html;
            server_name example.com www.example.com fwfiles.example.com;
           ## Only requests to our Host are allowed
            if ($host !~ ^(example.com|www.example.com)$ ) {
               return 403;
            }
           ## redirect www to nowww
            if ($host = 'www.example.com' ) {
               rewrite  ^/(.*)$  http://example.com/$1  permanent;
            }
           ## Only allow these request methods
            if ($request_method !~ ^(GET|HEAD|POST)$ ) {
               return 444;
            }
           ## PROXY - Web
            location / {
              proxy_pass  http://examplebackend;
              proxy_cache            cache;
              proxy_cache_valid      200 24h;
              proxy_cache_use_stale  error timeout invalid_header updating http_500 http_502 http_503 http_504;
              proxy_ignore_headers   Expires Cache-Control;
              proxy_set_header        Host            $host;
              proxy_set_header        X-Real-IP       $remote_addr;
              proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
              if ( $blockspammers = yes ) {
                     return 403;
              }
            }
           # redirect server error pages to the static page /50x.html
              error_page   500 502 503 504  /50x.html;
              location = /50x.html {
                  root   html;
              }
              error_page 403 /example.com.403.html;
              location = /example.com.403.html {
                 root   html;
                 allow all;
              }
        }
      • Phoenix May 16, 2012, 7:04 pm

        Firstly, that’s a highly inefficient nginx conf file with all those IF conditions.

        Anyway, my error_pages blocks are exactly the same, except that I want the error pages across my site — at least the default ones — to be the same. So I have this:

        error_page 404 /404.html;
        location = /404.html {
        root /etc/nginx/html;
        internal;
        }
        error_page 403 /403.html;
        location = /403.html {
        root /etc/nginx/html;
        allow all;
        }
        error_page 500 502 503 504 /500.html;
        location = /500.html {
        root /etc/nginx/html;
        }

        Where /etc/nginx/html is CHMOD 777.

        Not working.

        Any ideas?

        • gonza October 10, 2012, 8:35 pm

          Phoenix, What you posted worked perfect! And the files don’t need to be 777.

          server {
          error_page 403 = /403.html;
          location = /403.html {
          root /var/www/FOLDER;
          internal;
          }
          error_page 404 = /404.html;
          location = /404.html {
          root /var/www/FOLDER;
          internal;
          }
          }

  • Joseph January 9, 2015, 4:17 pm

    Make sure that your custom error pages are still sending the correct status codes..

    Like a 403 should still be a 403 and not a 200..
    I had to do it like this..
    error_page 403 =403 /403.html;

    Otherwise the 403 would be cached in varnish which is not cool non attacking visitors.

Leave a Comment