Custom error pages (404, 500)
Custom error pages must return the correct HTTP status code, explain what went wrong in plain language, and offer the user a way forward without leaking implementation details.
What it is
A custom error page is the document a server returns when it cannot fulfil a request. The two pages every site needs are the 404 Not Found for missing resources and the 500 Internal Server Error for unexpected failures. The page must be styled to match the rest of the site and must return the matching HTTP status code in the response headers.
Why it matters
The status code is what crawlers, link checkers, and monitoring tools read. A “page not found” message that returns 200 OK is a soft 404: search engines index the error page, link checkers see no broken links, and analytics tools count failures as normal traffic. Google explicitly treats soft 404s as a quality problem.
For humans, a generic server error page or a stack trace damages trust and may leak file paths, framework versions, or database details that help an attacker. A custom page keeps users in the site and gives them an obvious next step.
How to implement
For a 404:
- Return HTTP status
404. Verify withcurl -I https://example.com/does-not-exist. - Set a clear heading: “We could not find that page.”
- Offer a search box, a link to the homepage, and links to the most visited sections.
- Keep navigation, header, and footer so the user can carry on browsing.
- Log the request so you can find broken inbound links.
For a 500:
- Return HTTP status
500. - Acknowledge the failure in one sentence. Do not show stack traces, framework names, or environment variables.
- Offer a retry, a link home, and a support contact if you have one.
- Log the underlying error server-side with a request ID and surface that ID to the user so support can correlate.
Configure both pages at the server or edge layer (Nginx error_page, Apache ErrorDocument, Cloudflare custom error pages, Netlify _redirects with status overrides) so they work even when the application is down.
Localise error pages too. On a multilingual site, the 404 a French visitor lands on should be in French — the URL prefix (/fr/this-page-does-not-exist) already tells the server which locale to render. Match the page’s lang attribute, translate the heading and copy, and keep the search box and home link pointed at the same locale.
Common mistakes
- Returning
200 OKfor a “page not found” message — the classic soft 404. - Redirecting all unknown URLs to the homepage with a
302. Search engines flag this as a soft 404 too. - Exposing stack traces, SQL errors, or framework debug pages in production.
- A 404 page that loads a heavy JavaScript bundle before showing the message.
- Forgetting the 500 page entirely, so users see the default web server error.
Verification
curl -I https://example.com/this-does-not-existreturnsHTTP/2 404.- Force a 500 in staging and confirm the response code and that no stack trace leaks.
- Check Google Search Console under Pages for “Soft 404” warnings.
- Run a link checker against your site and confirm broken links surface as 404s, not 200s.
Related topics
Sources & further reading
- RFC 9110 — HTTP Semantics: 404 Not Found — IETF
- RFC 9110 — HTTP Semantics: 500 Internal Server Error — IETF
- Google Search Central — Soft 404 errors — Google Search Central
- MDN — HTTP response status codes — MDN