What a 404 error page should do
A 404 is the HTTP status code a server sends when it has nothing at the requested address. The page the visitor sees alongside that code is up to you. Servers ship with a plain default, such as the white Apache page that says Not Found and names the server software. It is accurate, but it gives the visitor nothing to do except leave.
A custom 404 page replaces that default with your own design while keeping the status code. Two parts must both be right:
- The status code is what browsers, search engines and monitoring tools read. It must be
404, or 410 for content you have removed for good.
- The page body is what people read. It should look like your site, say clearly that the page could not be found, and offer the next step.
If you get the design right and the code wrong, you create a soft 404. That is a page which says not found but returns 200 OK, so search engines treat it as a real page with thin content. Google reports these as Soft 404 in Search Console and does not index them, but it keeps spending crawls on them. The 404 errors guide covers how to find and repair the broken links that send people to this page in the first place.
What to put on a custom 404 page
Keep the page short and useful. Visitors arrive confused, so the first lines should tell them what happened in plain words, and the rest should get them moving again.
| Element | Why it helps | Example |
| Clear heading | Says what happened without jargon | Sorry, we cannot find that page |
| Short explanation | Suggests why, without blame | It may have moved, or the link may be mistyped. |
| Search box | Lets visitors look for what they wanted | A search form posting to your site search |
| Three to six key links | Gives obvious next steps | Home, shop, services, contact, popular guides |
| Normal header and footer | Shows they are still on your site | Your usual navigation |
| Contact or report link | Lets people tell you about a broken link | Email or a short form |
| Image or illustration | Softens the moment and matches your brand | A small, light image with alt text |
Avoid automatic redirects to the home page after a few seconds. Visitors lose the address they typed, they cannot tell what went wrong, and search engines may treat the redirect as a soft 404. Avoid long apologies, jokes that hide the message and pages that show nothing but an image. The words should still make sense if the image never loads.
๐ก Use your own data to choose the links. Your analytics or server logs show which missing addresses get the most visits, and that usually tells you which pages people were looking for.
Using a page not found image
A page not found image is optional. When used well, it makes the page feel deliberate rather than broken. When used badly, it is a heavy file that delays the only page a lost visitor sees.
- Use your own or properly permitted artwork. A photo from your shop, a simple illustration or your logo in a playful pose all work. Check the usage terms of any stock or free image before you use it.
- Keep it small. An SVG illustration is often a few kilobytes. A photo should be a compressed WebP or AVIF file of about 100 KB or less, sized for the space it fills.
- Give it alt text that describes the image, or an empty
alt="" if it is purely decorative. Never put the only explanation inside the image.
- Use an absolute path. The 404 page is shown at any missing address, so an image linked as
images/lost.svg breaks at /blog/2024/old-post. Use /images/lost.svg.
A light inline SVG avoids any extra request at all:
<svg width="160" height="120" viewBox="0 0 160 120" role="img" aria-label="An empty cake stand">
<ellipse cx="80" cy="96" rx="60" ry="8" fill="#d9d4cc"/>
<rect x="74" y="60" width="12" height="36" fill="#b8b0a4"/>
<ellipse cx="80" cy="58" rx="48" ry="6" fill="#b8b0a4"/>
</svg>
A simple 404 page template
This is a complete, plain HTML 404 page you can adapt. It uses absolute paths for every link and asset, carries a search form and key links, and asks search engines not to index it, which is harmless on a page that already returns 404:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex">
<title>Page not found | Example Bakery</title>
<link rel="stylesheet" href="/css/site.css">
</head>
<body>
<main>
<img src="/images/empty-cake-stand.svg" alt="An empty cake stand" width="160" height="120">
<h1>Sorry, we cannot find that page</h1>
<p>It may have moved, or the link may have a typing error.</p>
<form action="/search" method="get">
<label for="q">Search the site</label>
<input id="q" name="q" type="search">
<button type="submit">Search</button>
</form>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/cakes/">Our cakes</a></li>
<li><a href="/contact/">Contact us</a></li>
</ul>
</main>
</body>
</html>
Do not add a canonical tag to the 404 page. It is served at many addresses, and a canonical pointing at one of them, or at the home page, sends a confusing signal. The label on the search field matters for screen reader users; the accessible error messages guide covers the wording side.
Setting up the 404 page on Apache, nginx, WordPress and static hosts
Apache
Upload the page as /404.html, then add one line to .htaccess in the site root or to the virtual host:
ErrorDocument 404 /404.html
Use a local path starting with a slash. If you give a full address such as https://www.example.com/404.html, Apache sends a redirect to that page instead, and the original 404 status is lost.
nginx
server {
error_page 404 /404.html;
location = /404.html {
internal;
}
location / {
try_files $uri $uri/ =404;
}
}
The internal line stops people loading /404.html directly with a 200 status. Never write error_page 404 =200, which turns every missing page into a soft 404. Test with sudo nginx -t and reload with sudo systemctl reload nginx. On Plesk, the same settings live under the domain's Apache and nginx settings; see the Plesk HTTP errors guide.
WordPress
WordPress sends a 404 status for any address it cannot match and shows the theme's 404 template. In a classic theme that is 404.php; in a block theme, open Appearance, then Editor, then Templates, and edit the Page: 404 template. Add your heading, a search block and links there. Check that no plugin is set to redirect every 404 to the home page. More in the WordPress HTTP errors guide.
Static hosts and frameworks
Netlify, GitHub Pages and Cloudflare Pages all serve a file named 404.html at the root of the published folder with a real 404 status. In Next.js, a not-found file in the app folder does the same job; the Next.js error pages guide covers it.
How to check the 404 page returns the right status
Request an address that cannot exist and print only the status code:
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.com/this-page-does-not-exist-7391
You want 404. If you see 200, you have a soft 404. If you see 301 or 302, something is redirecting missing pages, usually a plugin or an ErrorDocument with a full address. Follow it with curl -sIL to see where it goes.
Check a deeper address too, such as /blog/2019/missing/, and open it in a browser. If the styling or image breaks only at depth, a relative path is to blame. In the Chrome DevTools Network panel, the first row should show status 404 and every asset below it should show 200. Search Console's URL Inspection live test should report the page as not found rather than indexable.
The fix, step by step
Step 1
Check what missing pages return now
Run curl -s -o /dev/null -w "%{http_code}" against an address that cannot exist on your site, such as /no-such-page-7391. Note whether the result is 404, 200 or a redirect. Open the same address in a browser and note what visitors see. This gives you a baseline. If you already get 404 and a branded page, skip to improving the content; otherwise the status or the page needs fixing.
Step 2
Write the page content
Draft a short heading that says the page cannot be found, one sentence suggesting why, a search box, three to six links to your most useful pages and a way to report the broken link. Pick the links using your analytics or server logs, choosing pages people most often wanted. Keep your normal header and footer. Read it aloud: a visitor should know what happened and where to go next within a few seconds.
Step 3
Add a light image if you want one
Choose your own illustration or a properly permitted image that fits your brand. Export it as a small SVG or a compressed WebP of about 100 KB or less. Reference it with an absolute path such as /images/lost.svg, set width and height to avoid layout shift, and give it alt text or an empty alt if it is decorative. Confirm in DevTools that it loads at a deep missing address.
Step 4
Build the 404 template
Create 404.html for a static or hand-built site, edit 404.php in a classic WordPress theme, or edit the Page: 404 template in a block theme. Use absolute paths for every stylesheet, script, image and link. Add noindex in the head if you like, but no canonical tag. Load the template directly in a browser to check the layout before wiring it into the server.
Step 5
Wire it into the server
On Apache add ErrorDocument 404 /404.html to .htaccess or the virtual host, using a local path. On nginx add error_page 404 /404.html; and mark the location as internal, then run sudo nginx -t and reload. On Netlify, GitHub Pages or Cloudflare Pages, place 404.html at the root of the published folder. In WordPress, the theme template is used automatically once saved.
Step 6
Remove soft 404 behaviour
Look for anything that turns missing pages into something else: plugins that redirect all 404s to the home page, nginx rules using =200, an ErrorDocument with a full address or a JavaScript app that returns 200 for every route. Switch these off or change them so unknown addresses return 404. Keep genuine redirects for pages that moved, and use 410 for content removed for good.
Step 7
Test status and layout at depth
Request two or three missing addresses at different depths with curl and confirm each returns 404. Open them in a browser and check the image, styles and links all work. In the Chrome DevTools Network panel, the document row should show 404 and every asset should show 200. Run the URL Inspection live test in Search Console on one of them and confirm it reports the page as not found.
Step 8
Monitor 404s and fix the causes
Each month, filter your server logs or analytics for 404 responses and sort by visits. Redirect missing addresses that have a clear replacement, fix internal links that point to missing pages and leave genuine junk requests alone. Check the Page indexing report in Search Console for new Soft 404 entries, which usually mean a recent change broke the status code, and re-run the curl test after every deployment.
Edge cases worth knowing
- Single-page apps. A JavaScript app often returns 200 for every path and draws a not found view in the browser. Return a real 404 from the server for unknown routes, or Google may flag them as soft 404s.
- Removed for good. Use
410 Gone for content you have deliberately deleted with no replacement. It shows the same custom page if you set ErrorDocument 410 or error_page 410 too.
- Pages that moved. A custom 404 page is not a substitute for a redirect. If the content exists at a new address, set up a 301 redirect.
- Caching. Some CDNs cache 404 responses. After publishing a page that was previously missing, purge the cache or it can keep showing not found.
- Heavy 404 pages. Bots request missing addresses constantly. A 404 page that runs database queries or loads large scripts adds real server load. Keep it light.
Keeping the 404 page working
The 404 page is easy to break without noticing, because nobody visits it on purpose. Add these to your routine:
- Test the status after every theme, plugin or server change with the curl command above.
- Track 404 visits. Send an analytics event from the 404 template with the requested address, or filter your server logs for 404 responses, and fix the most visited ones with redirects.
- Crawl for broken internal links. Your own links should never lead to the 404 page. The broken internal links guide shows how to find them.
- Review Search Console. The Page indexing report lists Not found (404) and Soft 404 addresses. A new Soft 404 group often means a change has broken the status code.
Questions and answers
1. How do I fix my 404 error page?
You fix a 404 error page by making sure it returns a real 404 status code and replacing the plain server default with a helpful page of your own. Create a branded page with a clear message, a search box and a few useful links, then point your server at it with ErrorDocument on Apache, error_page on nginx, the 404 template in WordPress or a 404.html file on static hosts. Finally test a missing address with curl and confirm the status is 404, not 200 or a redirect.
2. What is a soft 404?
A soft 404 is a page that tells visitors the content cannot be found but returns a 200 OK status, so search engines see a working page with little or no content. Google detects many of these and reports them as Soft 404 in Search Console, and they are not indexed. Common causes are 404 pages served with the wrong status, redirects of every missing page to the home page and JavaScript apps that return 200 for unknown routes. Fix the server so missing addresses return 404.
3. Should I redirect all 404 pages to my home page?
No, redirecting every missing page to the home page is usually a mistake. Visitors lose track of what they were looking for, and Google tends to treat mass redirects to the home page as soft 404s, so you gain nothing in search. Redirect a missing address only when there is a genuinely matching page, such as a renamed product or a moved article. For everything else, show a helpful custom 404 page with a proper 404 status and let the visitor choose where to go.
4. Where can I get a page not found image?
The best page not found image is one you make or commission yourself, such as a simple illustration, a photo from your business or your logo used playfully, because it matches your brand and avoids usage questions. If you use stock or free artwork, check its usage terms first. Keep the file small, ideally an SVG or a compressed WebP, give it alt text, and link it with an absolute path so it loads at every missing address on the site.
5. Do 404 errors hurt SEO?
No, 404 errors on addresses that should not exist do not hurt your site's rankings, and Google says they are a normal part of the web. They become a problem when important pages go missing, when your own internal links point to missing pages, or when valuable backlinks lead to a 404 and the link value is lost. Fix those cases with redirects or restored pages, keep the 404 status for the rest and make the 404 page helpful for visitors.
6. Why does my custom 404 page lose its styling?
A custom 404 page loses its styling when it uses relative paths for stylesheets, scripts or images. Because the same page is shown at every missing address, a link such as css/site.css is looked up relative to the missing path, so it works at the top level but fails deeper in the site. Change every asset and link on the 404 page to an absolute path that starts with a slash, such as /css/site.css, then test a deep missing address in the browser.
7. Should a 404 page be noindex?
A 404 page does not need noindex, because search engines do not index pages that return a 404 status, but adding it does no harm. The status code is what really matters. If your 404 page returns 200 by mistake, noindex stops it being indexed, but Google may still report it as a soft 404 and keep crawling it, so fix the status code rather than relying on the tag. Do not add a canonical tag to a 404 page.
Check your 404 page returns a real 404
The HTTP error audit tests missing addresses on your site, flags soft 404s and redirects to the home page, and lists the broken links that send visitors to your 404 page.
Open HTTP Error Fixes โ