NewHalo Edge 3 is here: HTTP/3 everywhere and 42 edge locations.Learn more
Docs / Web servers

Create custom error pages

Web servers5 min readUbuntu 24.04 LTS

When something goes missing or breaks, visitors should see a helpful page instead of a bare server message. This guide adds a custom 404 (not found) page and a custom 50x (server error) page to an nginx site.

Before you begin

  • A working nginx site, such as the one from Host a static website, with its server block at /etc/nginx/sites-available/example.com.
  • SSH access and a user with sudo rights.
  • Basic comfort with HTML. The pages in this guide are short and easy to edit.

Step 1: See the current error behavior

Request a page that does not exist. The -i flag shows the response headers as well as the body, so you can see the status code.

curl -i http://example.com/no-such-page
HTTP/1.1 404 Not Found
Server: nginx/1.24.0 (Ubuntu)
Content-Type: text/html

<html>
<head><title>404 Not Found</title></head>
...

That generic page works, but it does not match your site. The status code (404) is what search engines and tools rely on, so your custom page must keep the same status code. nginx does that for you.

Step 2: Create the error page files

Keep error pages in their own folder, separate from the site files, so they are never mixed up with your content. Create the folder, then open a new file for the 404 page.

sudo mkdir -p /var/www/example.com/errors
sudo nano /var/www/example.com/errors/404.html

Paste in a simple page. Change the wording and links to suit your site:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Page not found</title>
</head>
<body>
  <h1>Page not found</h1>
  <p>That page does not exist. <a href="/">Return to the home page</a>.</p>
</body>
</html>

Create the server error page the same way:

sudo nano /var/www/example.com/errors/50x.html

Use a friendly message such as "Something went wrong on our side. Please try again in a few minutes." Keep the same HTML structure as the 404 page.

Step 3: Point nginx at the error pages

Open your server block and add the lines below inside the existing server { } block, after the location / { } section.

sudo nano /etc/nginx/sites-available/example.com
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;

    location = /404.html {
        root /var/www/example.com/errors;
        internal;
    }

    location = /50x.html {
        root /var/www/example.com/errors;
        internal;
    }

The error_page lines tell nginx which internal address to show for each error. The internal keyword means visitors cannot request those pages directly. Each location block points at the error folder instead of your site folder.

Step 4: Check the config and reload nginx

Test the configuration, then reload nginx so the change takes effect:

sudo nginx -t
sudo systemctl reload nginx

nginx workers run as the www-data user, so they must be able to read the new folder. If you see permission errors later, run this to make the folder and files readable:

sudo chmod -R a+rX /var/www/example.com/errors

Step 5: Test the 404 page

curl -i http://example.com/no-such-page
HTTP/1.1 404 Not Found
Content-Type: text/html

<!DOCTYPE html>
<html lang="en">
...
<h1>Page not found</h1>

The status is still 404, and the body is your new page.

Step 6: Test the 50x page safely

You do not want to break your live site to test a server error. Instead, add a temporary test location that returns a 500 error, check it, and then remove it. Add this inside the server block:

    location = /test-error {
        return 500;
    }
sudo nginx -t
sudo systemctl reload nginx
curl -i http://example.com/test-error

You should see your 50x page with a 500 status. Now delete the temporary block, run sudo nginx -t and sudo systemctl reload nginx again.

Careful: Remove the test location when you finish. Leaving a deliberate error route in place confuses visitors and monitoring tools.

Apache users

If your site runs on Apache instead, copy the 404 page into your document root (for example /var/www/example.com/html/errors/404.html). Then add this line inside your <VirtualHost> block and reload Apache with sudo systemctl reload apache2:

ErrorDocument 404 /errors/404.html

Troubleshooting

  • The default nginx page still appears. Confirm that the error lines are inside the server block for your domain, then run sudo nginx -t and reload nginx.
  • The error page is blank or shows a nested 404. The file path is wrong. Check it with ls -l /var/www/example.com/errors and make sure the file names match the error_page lines exactly.
  • Permission denied in the error log. Run the chmod command from Step 4 and reload nginx.
  • Some browsers replace very small error responses with their own page. Make your error pages a few hundred bytes or more, and test in a private window.

Next steps

Once your error pages are in place, consider enabling HTTPS so that all pages, including the error pages, are served securely. Keep your error pages simple and link back to the home page so visitors can recover quickly.

Something not working? Chat or email our support team and we will help you get unstuck.

Contact support