Accessibility & HTML · Checked once per domain
Custom 404 error pageWhat it checks and how to fix it
What it checks
Requests a URL that cannot exist on the site and inspects the answer. It passes when the server responds with a 404 status and a real page (a title or substantial content, not the bare nginx or Apache default); it warns when the error page is a generic server page, or when the missing URL does not answer 404 at all (a soft 404).
Why it matters
Visitors land on missing pages through old links, typos and moved content. A branded 404 with navigation and search keeps them on the site, while a bare server page sends them back to the search results. Answering missing URLs with 200 instead of 404 also lets search engines index junk URLs as duplicate content.
How to fix it
Serve a branded page for missing URLs, and keep the 404 status code.
<!-- 404.html -->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Page not found</title></head>
<body>
<header><!-- site navigation --></header>
<main>
<h1>Page not found</h1>
<p>The page you are looking for does not exist or has moved.</p>
<a href="/">Back to the homepage</a>
</main>
</body>
</html>
nginx:
error_page 404 /404.html;
error_page 500 502 503 504 /500.html;
location = /404.html { internal; }
Apache (.htaccess):
ErrorDocument 404 /404.html
ErrorDocument 500 /500.html
Rails: edit public/404.html and public/500.html, or render your own templates by setting config.exceptions_app = routes and routing /404 to a controller that renders with status: :not_found.
Cloudflare Pages serves a top-level 404.html automatically. For single-page apps, make sure the catch-all route returns status 404 for unknown paths instead of 200.