Why is my website showing 404 errors? A checklist for site owners
A 404 Not Found tells visitors and search engines that nothing exists at the address they asked for. Some 404s are normal and harmless, such as mistyped addresses or old spam links. Others cost you visitors and search traffic: pages that moved without a redirect, internal links pointing at the wrong address, a WordPress setting that suddenly breaks every post, or a product handle changed in Shopify. This guide shows how to find the 404s that real visitors and crawlers actually hit, how to decide what each missing URL should do, the redirect rules for WordPress, Shopify, Apache and nginx, how to make a custom error page that still returns the right status code, and how to keep new 404s from piling up after the next redesign.
- What a 404 is, and when it is fine
- Where 404s come from
- How to find the 404s that matter
- Deciding what each missing URL should do
- Platform notes: WordPress, Shopify, Apache and nginx
- A worked example: one rule for thousands of URLs
- The fix, step by step
- Edge cases worth knowing
- Keeping it fixed
- Questions and answers
What a 404 is, and when it is fine
A 404 Not Found is the server's way of saying it has nothing at that address. It does not say whether something used to be there or might be later. A 410 Gone is the deliberate version: the page existed and has been removed on purpose.
A 404 is not a penalty. Google states plainly that 404s on URLs that should not exist do not harm how the rest of your site ranks. Every site collects them from typos, scrapers, old campaigns and bots probing for files such as /wp-login.php on sites that do not run WordPress. Those can be left alone.
A 404 becomes a problem in three situations:
- The page moved. The content still exists at a new address, but the old address has links, bookmarks or search traffic and no redirect.
- Your own site links to it. A broken internal link wastes visitors' time and sends crawlers to a dead end on every crawl.
- Pages that should work are failing. A whole section, or every post, suddenly returns 404 because of a configuration change, not because anything was deleted.
Where 404s come from
| Cause | Typical sign | Fix |
|---|---|---|
| Page renamed or moved | Old URL in links, bookmarks or Search Console | 301 redirect to the new address |
| Permalink or URL structure changed | Hundreds of old URLs failing in one pattern | One pattern-based redirect rule |
| Typo in an internal link | A crawler finds the 404 linked from your own page | Correct the link |
| WordPress rewrite rules lost | Home page works, every post and page fails | Save permalinks; check nginx try_files |
| Product or collection handle changed | Shopify product links from ads or emails fail | Shopify URL redirect |
| Content deleted with no replacement | Old blog post or discontinued product | Leave as 404 or return 410 |
| Site migration | Many old URLs fail after launch | Redirect map from old to new |
| Bad links from other sites | Odd URLs with extra characters in logs | Redirect if the link is valuable, otherwise ignore |
After a move to a new platform the same table applies on a larger scale, and the migration redirects guide covers building the full map.
How to find the 404s that matter
Use three sources, because each shows a different slice:
- Search Console. The Page indexing report lists URLs under Not found (404). These are addresses Google knows about, from links, sitemaps or its own history. Click a URL and use URL Inspection to see where Google found it.
- A site crawler. A crawl starts from your home page and follows your own links, so every 404 it finds is one you created. Those are the first to fix.
- Server access logs. Logs show what real visitors and bots actually requested and how often. A 404 hit 300 times a week from a referrer matters far more than one hit once by a scanner.
To pull the most requested 404s from a standard nginx or Apache access log, run this on the server:
sudo awk '$9 == 404 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -n 30
Field 9 is the status code and field 7 the path in the common combined log format. On Plesk, the domain's log is /var/www/vhosts/system/example.com/logs/access_ssl_log. To see where visitors to one missing URL came from, filter on that path and print the referrer:
sudo grep ' /old-services/ ' /var/log/nginx/access.log | awk '$9 == 404 {print $11}' | sort | uniq -c | sort -rn
Then confirm the response for any URL with curl -sI https://www.example.com/old-services/. The first line should read HTTP/2 404 for a page that is truly gone and HTTP/2 301 for one you have redirected. Our 404 errors guide for audits explains how to read the same findings in a crawl report.
Deciding what each missing URL should do
Work through the list and give every URL one of four outcomes:
| Situation | Response |
|---|---|
| Same content now lives at a new address | 301 to the new address |
| Gone, but a close replacement exists, such as a newer model of the same product | 301 to the replacement |
| Gone for good, nothing similar | 404, or 410 if you want to be explicit |
| Never existed, or junk from bots | Leave the 404 |
Do not redirect every missing page to the home page. Visitors who wanted a specific product land somewhere unrelated, and Google often treats a redirect to an irrelevant page as a soft 404 anyway, so you gain nothing. A redirect should land on a page that satisfies the same need. For more on choosing between redirect types, see fixing redirect chains, which also explains why each old URL should point straight at its final address.
Platform notes: WordPress, Shopify, Apache and nginx
WordPress
If the home page loads but every post and page returns 404, the rewrite rules are missing or stale. Open Settings, then Permalinks, and click Save Changes without changing anything. WordPress rebuilds its rules and, on Apache, rewrites the WordPress block in .htaccess if it can. On nginx there is no .htaccess, so the server block must pass unknown paths to WordPress:
location / {
try_files $uri $uri/ /index.php?$args;
}
For individual moved pages, a redirect plugin such as Redirection lets you add old and new paths without touching server files, and logs 404s so you can see new ones as they appear. WordPress also tries to guess the right post when a URL is close to a real one, which is why some mistyped addresses redirect on their own. Redirects in WordPress covers the plugin options.
Shopify
Shopify keeps redirects in its URL redirects list, reached from Online Store, then Navigation, or from Content, then Menus in newer admin layouts. When you edit a product or collection handle, the search engine listing section offers a tick box to create a redirect from the old URL; leave it ticked. You can also import redirects in bulk from a CSV file with two columns, the old path and the new address.
Apache and nginx
For a single page, use a plain permanent redirect:
# Apache, in .htaccess or the virtual host
Redirect 301 /old-services/ https://www.example.com/services/
# nginx, inside the server block
location = /old-services/ { return 301 https://www.example.com/services/; }
For a page that is gone on purpose, Apache's Redirect gone /old-offer/ returns 410, and in nginx location = /old-offer/ { return 410; } does the same.
A worked example: one rule for thousands of URLs
A blog changes its WordPress permalink setting from day and name, giving addresses such as /2026/10/17/post-name/, to post name only, giving /post-name/. WordPress itself often redirects old date-based links, but this site sits behind a static cache that serves its own 404 first, and thousands of old links from social media and other sites now fail. Search Console's Not found (404) count climbs every day.
Adding one redirect per post would take days. Every old URL follows the same pattern, so one rule handles all of them. In nginx:
rewrite ^/[0-9]{4}/[0-9]{2}/[0-9]{2}/([^/]+)/?$ /$1/ permanent;
Or in Apache:
RedirectMatch 301 ^/[0-9]{4}/[0-9]{2}/[0-9]{2}/([^/]+)/?$ /$1/
The pattern requires a slug after the date, so date archive pages such as /2026/10/ are not caught. A quick check with curl -sI on three old links shows each returning 301 with a location header pointing at the new address, which then returns 200. Over the following weeks the 404 count in Search Console falls as Google recrawls the old URLs.
The fix, step by step
Step 1
Collect the 404s from three sources
Export the Not found (404) list from the Page indexing report in Search Console, run a crawl of your site, and pull the most requested 404 paths from your server access log with awk. Put them into one spreadsheet with a column for hits, a column for where each link comes from, and a column for the decision. This gives you the full picture before you start changing anything, and shows which URLs real visitors actually request.
Step 2
Fix broken internal links first
Sort the crawl results by the 404s your own pages link to. Open each linking page, correct the link to the right address, and save. In WordPress, search the post content for the old path to catch every instance, including menus and widgets. Recrawl to confirm the 404 no longer appears as linked from your site. These fixes matter most because every visitor and every crawl hits them, and they are entirely within your control.
Step 3
Check for a site-wide rewrite problem
If most posts or pages fail while the home page works, the rewrite rules are broken, not the content. In WordPress, open Settings, then Permalinks, and click Save Changes. On nginx, check that the server block has try_files $uri $uri/ /index.php?$args; in the main location. On Apache, check .htaccess still contains the WordPress block. Reload a few posts and confirm they return 200 before carrying on with individual URLs.
Step 4
Decide an outcome for each URL
For every remaining 404, mark one of four outcomes in the spreadsheet: redirect to the new address, redirect to a close replacement, leave as 404 or 410, or ignore as junk. Check traffic and backlinks for anything you plan to leave as a 404. Do not send unrelated URLs to the home page. A decision made for every row stops you adding redirects on impulse and gives you a record for the next redesign.
Step 5
Add the redirects
Add 301 redirects for every moved or replaced page, using a redirect plugin in WordPress, the URL redirects list in Shopify, or Redirect 301 in Apache and return 301 in nginx. Where many URLs share a pattern, use one pattern rule instead of hundreds of single lines. Point each old URL straight at its final address. Test a sample with curl -sI and confirm a single 301 followed by a 200.
Step 6
Return 410 for content that is gone
For pages removed on purpose with no replacement, either leave the 404 in place or return 410 Gone to say the removal is deliberate. In Apache use Redirect gone /path/, and in nginx return 410; inside a matching location block. Shopify and most hosted platforms return 404 for deleted pages, which is fine. Check the response with curl to confirm the status code and that the page no longer appears in your sitemap.
Step 7
Make the 404 page helpful and correct
Design a custom 404 page with your navigation, a search box and links to popular pages. Set it up with ErrorDocument 404 /404.html in Apache or error_page 404 /404.html; in nginx, using a path rather than a full address. Request a made-up URL with curl -sI and confirm the first line shows 404, not 200 or 302. A friendly page that returns 200 is reported by Google as a soft 404.
Step 8
Validate in Search Console
Once the redirects and links are in place, open the Not found (404) reason in the Page indexing report and click Validate fix. Google rechecks the listed URLs over the following days or weeks. Spot check a few with URL Inspection, which shows the redirect target or the 404 Google now sees. Expect the count to fall gradually, and remember that deliberate 404s for removed content will still be listed, which is correct.
Edge cases worth knowing
- Soft 404s. A friendly error page that returns
200 OKis reported by Google as a soft 404. The page must return status 404 or 410. In Apache,ErrorDocument 404 /404.htmlworks, but giving a full address such ashttps://www.example.com/404.htmlmakes Apache redirect instead, and the status is lost. In nginx, useerror_page 404 /404.html;without the=200option. - Thin or empty pages. Empty category pages and out-of-stock product pages with no content can also be classed as soft 404s even though they return 200.
- 404 versus 410. Both remove a page from the index over time. A 410 is a slightly stronger signal and may be acted on a little sooner, but a 404 is fine for most cases.
- Images and files. Missing images, PDFs and scripts are 404s too. A missing stylesheet can break a page's layout for visitors and for Google's rendering.
- Sitemaps listing dead URLs. A sitemap should only list live pages. See fixing sitemap 404s if Search Console shows URLs from your sitemap returning 404.
Keeping it fixed
Make the 404 page useful. Include your main navigation, a search box and links to your most popular pages, so visitors who reach it can carry on. Keep the status code at 404 and test it with curl -sI https://www.example.com/this-does-not-exist/ after any theme change.
Build redirects into your routine. Whenever you rename a page, change a slug or remove a product, add the redirect at the same time. Keep a simple spreadsheet of old and new addresses during any redesign. After launch, crawl the site, check the 404 report in your redirect plugin or logs weekly for a month, and look at Search Console's Page indexing report. The HTTP error audit guide explains how to schedule regular checks.
1. Do 404 errors hurt my SEO?
No, 404 errors on URLs that should not exist do not harm the rest of your site in Google's ranking. Google expects every site to have some. The harm comes indirectly: a moved page with no redirect loses the links and traffic it had built up, and broken internal links send visitors and crawlers to dead ends. Fix the 404s that have traffic, backlinks or internal links pointing at them, and leave genuine junk URLs alone without worrying about them.
2. Should I redirect all 404 pages to my home page?
No, redirecting every missing page to the home page is a poor fix for visitors and for search engines. Someone looking for a specific product or article lands on a page that does not answer their need, and Google often treats a redirect to an unrelated page as a soft 404, so the old URL gains nothing. Redirect only to a page that covers the same topic or a close replacement, and let truly gone pages return a 404 or 410.
3. Why are all my WordPress posts showing 404?
When every post returns 404 but the home page works, the rewrite rules that map pretty URLs to WordPress are missing or out of date. Go to Settings, then Permalinks, and click Save Changes without altering anything; this rebuilds the rules. On Apache, check the .htaccess file is writable and contains the WordPress block. On nginx, the server block needs a try_files rule that passes unknown paths to index.php, because nginx does not read .htaccess files at all.
4. What is the difference between a 404 and a 410?
A 404 says nothing is at the address, while a 410 says something was there and has been removed on purpose. Both lead Google to drop the URL from its index over time. A 410 can be acted on slightly sooner because it is an explicit signal, but the difference is small. Use 410 when you are certain a page is not coming back, such as a closed promotion, and a 404 for everything else.
5. What is a soft 404?
A soft 404 is a page that tells the visitor it does not exist, or has almost no content, but returns a 200 OK status code instead of 404. Google detects these and reports them as Soft 404 in the Page indexing report. They usually come from a custom error page set up incorrectly, from empty category or search pages, or from redirecting removed pages to unrelated ones. Make missing pages return a real 404 or 410 and give thin pages real content.
6. How long does it take for 404 errors to clear in Search Console?
It usually takes from a few days to several weeks, because Google has to recrawl each URL before the report changes. Popular URLs are recrawled quickly, while rarely visited ones can take months. Clicking Validate fix asks Google to recheck the listed URLs and tracks progress. URLs that correctly return 404 because the content is gone will stay in the report as not found, which is expected and does not need any further action from you.
7. Why does Search Console show 404s for pages I never created?
Google finds URLs from links anywhere on the web, so 404s for pages you never created usually come from other sites linking incorrectly, scrapers, spam, or old URLs from a previous owner of the domain. URL Inspection sometimes shows the referring page. If the URL has no real traffic and no valuable link, ignore it, because a 404 is the correct answer. If a genuine site links to a mistyped version of a real page, redirect it to the right address.
The HTTP error audit on aiwebpageseo.com crawls your site, lists every URL that returns 404 or 410 and shows which of your own pages link to them, so you fix the source rather than the symptom.
Open HTTP Error Fixes โ