NGINX: Create Custom 404 / 403 Error Page

by on November 17, 2010 · 11 comments· LAST UPDATED November 17, 2010

in , ,

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

TwitterFacebookGoogle+PDF versionFound an error/typo on this page? Help us!

{ 11 comments… read them below or add one }

1 yoyo August 9, 2011 at 8:43 pm

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

Reply

2 khupcom September 19, 2011 at 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.

Reply

3 Phoenix May 16, 2012 at 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?

Reply

4 nixCraft May 16, 2012 at 5:27 pm

Try any one of the following context:

  1. http
  2. server
  3. location
  4. if in location

Reply

5 Phoenix May 16, 2012 at 5:28 pm

Thanks Vivek. Can I do outside http?

Reply

6 Phoenix May 16, 2012 at 5:29 pm

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

Reply

7 cybernet July 6, 2014 at 7:21 am

644
files should always have 644 and directories 755

Reply

8 Phoenix May 16, 2012 at 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.

Reply

9 nixCraft May 16, 2012 at 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;
        }
  }

Reply

10 Phoenix May 16, 2012 at 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?

Reply

11 gonza October 10, 2012 at 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;
}
}

Reply

Leave a Comment

Tagged as: , , , , , , , , , , , , , , , , ,

Previous Faq:

Next Faq: