Websites & apps

Custom error pages in Nginx and Apache: 404, 403, 500 and 503

Replace default server error pages with branded ones: ErrorDocument in Apache and .htaccess, error_page in Nginx, a maintenance 503 page, and how to keep the right status codes for SEO.

BeginnerLinux VPS and hosting3 min read

The default error pages from a web server are plain, technical and sometimes reveal the server version. Custom error pages keep visitors on your site with your branding, a search box and helpful links, while still returning the correct HTTP status code to browsers and search engines.

Before you start

  • An error page per status, saved as static HTML (e.g. /errors/404.html). Static files keep working even when PHP or the database is down.
  • Use absolute paths for CSS and images inside error pages (/assets/style.css), because they are shown at any URL.
  • On cPanel hosting you can use cPanel → Advanced → Error Pages instead.

Which error pages to create

CodeMeaningWhat to show
404Not FoundSearch box, links to popular pages
403ForbiddenShort explanation and a contact link
500Internal Server ErrorApology, "try again shortly"
502 / 504Bad Gateway / Gateway TimeoutSame as 500
503Service UnavailableMaintenance message and expected return time

Apache and .htaccess: ErrorDocument

In the vhost or in .htaccess (works on LiteSpeed too):

ErrorDocument 404 /errors/404.html
ErrorDocument 403 /errors/403.html
ErrorDocument 500 /errors/500.html
ErrorDocument 503 /errors/503.html

Warning: use a local path, not a full URL. ErrorDocument 404 https://example.com/404.html makes Apache send a 302 redirect, so search engines see a redirect instead of a 404 (a "soft 404").

Nginx: error_page

error_page 404 /errors/404.html;
error_page 500 502 504 /errors/500.html;
error_page 503 /errors/503.html;

location ^~ /errors/ {
    internal;
    root /var/www/example.com;
}
  • internal stops visitors from loading the pages directly at /errors/....
  • To show custom pages for errors coming from PHP-FPM or a proxied app, add fastcgi_intercept_errors on; or proxy_intercept_errors on;. Otherwise Nginx passes the app's own error body through.
  • Don't write error_page 404 = /index.php; unless you mean it: the = lets the target's status (usually 200) replace the 404.

A maintenance 503 page

For planned work, return 503 with Retry-After so search engines come back later instead of indexing the maintenance page.

Nginx

if (-f /var/www/example.com/maintenance.on) { return 503; }
error_page 503 @maintenance;
location @maintenance {
    root /var/www/example.com/errors;
    rewrite ^ /503.html break;
    add_header Retry-After 3600 always;
}

Create maintenance.on to switch it on, delete it to switch it off; no reload needed.

Apache / .htaccess

RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/maintenance.on -f
RewriteCond %{REQUEST_URI} !^/errors/
RewriteCond %{REMOTE_ADDR} !^203\.0\.113\.10$
RewriteRule ^ - [R=503,L]
ErrorDocument 503 /errors/503.html
Header always set Retry-After "3600" "expr=%{REQUEST_STATUS} == 503"

The REMOTE_ADDR line lets your own IP through to test the site.

Check the status codes

curl -s -o /dev/null -w "%{http_code}\n" https://example.com/this-does-not-exist

It must print 404, not 200 or 302, while the browser shows your custom page.

Troubleshooting

  • Custom page never shows: the app (WordPress, Laravel) handles 404s itself; customise its theme template instead, or enable intercept_errors in Nginx.
  • Error page without styles: relative asset paths. Use absolute paths.
  • 500 page itself fails: it depends on PHP. Keep error pages static.

FAQ: custom error pages

Are custom 404 pages good for SEO?

Yes, as long as they return a real 404 status. They also reduce bounce rate.

Should I redirect all 404s to the homepage?

No. Search engines treat that as soft 404s. Redirect only moved pages, with 301s.

Can I show different error pages per site?

Yes. Define them in each vhost, server block or site's .htaccess.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.