Short answer: for Google Search, a 404 and a 410 do the same job. If the page was in Google, it comes out, and Google visits the URL less and less over time. A soft 404 is the one to worry about. The page tells a person "not found", but the server tells Google "200 OK, all fine", so Google keeps coming back. Use a 404 or 410 for pages that are gone for good. Use a 301 redirect only when there's a close replacement. Then check what your server really sends back, because that's where it usually goes wrong.
A quick word on the numbers. Every time a browser or Googlebot asks for a page, the server answers with a status code. 200 means "here it is". 301 means "it's moved for good, go here". 404 means "not found". 410 means "gone, on purpose".
What is the difference between 404 and 410?
A 404 says "I can't find this". A 410 says "this was here, and I removed it for good".
To people, that's a real difference. To Google Search, there's almost none. Google's status code doc says every 4xx code (the 400 range) is handled the same way, except 429, which means "too many requests". The URL is removed from the index if it was there, and Google crawls it less over time.
Google's crawl budget doc says the same thing in practical terms. Crawl budget is how many pages Google is willing to fetch from your site in a given time. The doc says to return a 404 or 410 for pages you've removed for good. Google won't forget a URL it knows about, but a 404 is a strong signal not to crawl it again.
So which should you use? I use a 410 when the platform makes it easy, because it records the intent. If it doesn't, a 404 is fine. I wouldn't spend a sprint changing one into the other.
What does a 410 status code mean?
A 410 Gone says the page existed and was removed on purpose, with no forwarding address. Think of it as a shop putting "closed for good" on the door instead of just switching the lights off. It's a clean way to retire old offers, expired listings, empty tag pages or thin pages you've decided to remove.
Do 404 errors hurt SEO?
Not on their own. Google's Crawl Stats help says it's "not possible, worthwhile, or even desirable" to fix every 404 on your site, and that a 404 is often the right answer when a page is truly gone with no replacement. Its Page indexing help says the same: 404s aren't necessarily a problem if the page was removed with no replacement.
Where 404s do cost you:
- A page that used to get traffic or links now returns 404, and there's a close replacement. Redirect it with a 301 so people and Google land somewhere useful.
- Your own internal links point at 404s. That's a bad experience for people and wasted crawling. Fix the links.
- A page you still want returns 404 by mistake. That's a bug, not an SEO choice.
What causes a 404 error?
Two things, mostly:
- The page was removed or moved, and nothing was put in its place.
- The link is wrong. A typo in a link on your site or someone else's, or an old URL that was never redirected.
Does a 404 mean blocked? And what about 401 and 403?
No. A 404 says "not found". Blocked is a different set of codes. A 401 asks for a login, and a 403 says "you're not allowed".
For Google, it comes to the same thing. Its status code doc handles every 4xx code (except 429) the same way, so a page that sends Googlebot a 401 or 403 drops out of the index just like a 404. Google's Page indexing help lists them as their own reasons ("Blocked due to unauthorized request (401)" and "Blocked due to access forbidden (403)"), and points out that Googlebot never logs in. So a 403 to Googlebot on a page you want indexed is a mistake on your side. If you're not sure whether it's really Googlebot getting those codes, see how to check Googlebot in your access logs.
What does soft 404 mean?
A soft 404 is a page that looks like an error but tells Google everything's fine. The person sees "not found" or an empty page. The server sends 200 OK.
Typical examples:
- an empty search or filter page that says "no results"
- a "this product is no longer available" page that still returns 200
- a thin template with almost nothing on it
- lots of old URLs all redirected to the home page
Here's what one looks like from the server side. The page says "Page not found", but the response says all is well:
curl -sI https://example.com/products/old-blue-kettle
HTTP/2 200
content-type: text/html; charset=utf-8
The fix is to make that same URL answer HTTP/2 404 or HTTP/2 410, and keep the friendly "not found" message for people.
Google's Page indexing help defines it as a page that "returns a user-friendly 'not found' message but not a 404 HTTP response code", and recommends a real 404 for pages that are truly not found. Google's site move doc warns that sending lots of old URLs to one unrelated page, such as the home page, can count as a soft 404.
What is the difference between a 404 error and a soft 404 error?
A 404 tells Google the truth in the status code. A soft 404 says the opposite of what the page shows.
That matters for crawling. Google's crawl budget doc says soft 404 pages keep getting crawled and waste your crawl budget. A real 404 or 410 does the opposite.
How to fix soft 404 errors in Google Search Console
- Find them. In Search Console, open the Page indexing report. Under "Why pages aren't indexed", click the Soft 404 reason. Open a few of the URLs in a browser.
- Decide what each page should be. Gone for good? Return 404 or 410. Moved to a close match? 301 to that page. Still useful? Make it a real page with real content, so it no longer looks empty.
- Fix the template, not the URL. Soft 404s nearly always come from one template or one rule. Fix it once.
- Stop redirecting removed pages to the home page. Send each one to its closest match, or let it return 404 or 410.
- Check the fix live. Paste a few URLs into the URL Inspection tool, run a live test, then open View tested page to see what Google got. When it looks right, click Validate fix on the Soft 404 row, so Google rechecks the rest.
One heads-up: older guides send you to the "Coverage" report or "crawl errors". Those are old names. Today it's the Page indexing report.
How to fix soft 404 errors in WordPress
The same steps work. In WordPress, soft 404s usually come from a handful of page types:
- Empty category, tag or author archives. WordPress returns 200 for an archive that exists but has no posts. So a tag with no posts is an empty list with a 200. Remove unused tags, or point them at a real page.
- Internal search results pages. WordPress returns 200 for a search with no results, too. Add a noindex robots meta tag to search results pages, and don't link to them.
- Media attachment pages. Older sites can have a near-empty page for each uploaded image. Since WordPress 6.4, new sites send attachment URLs straight to the file instead. Sites set up earlier keep the old pages until you change the wp_attachment_pages_enabled option to 0.
- "Out of stock" or "no longer available" pages that still return 200. If the product is gone for good, return 404 or 410, or 301 to a close match.
Change one setting, then run the URL Inspection live test on one URL of that type before you validate.
How to fix 404 errors in Google Search Console
Search Console lists 404s under the "Not found (404)" reason in the Pages report. Google says these aren't necessarily a problem. So I go through them in this order:
- Should this page exist? If yes, it's a bug. Restore it.
- Has it moved? If there's a close replacement, add a 301 to it.
- Is it gone for good? Leave the 404, or switch it to a 410. Nothing else to do.
- Who links to it? If your own pages link to it, fix those links. If your sitemap lists it, take it out.
You don't need to validate URLs you meant to remove. Google's help says it doesn't always make sense to fix and validate every issue, so use your judgement.
How do I clear a 404 error? And how to solve a 410 error
If the page is meant to be gone, there's nothing to clear. Leave the 404 or 410 in place. It's the right answer, and Google will visit the URL less over time.
The same goes for 410s you see in Search Console. A 410 is a deliberate "gone", so it doesn't need fixing. Only act if the page should be live (restore it) or has a close replacement (301 to it).
Should you 301, 404, 410 or noindex a removed page?
Here's the decision table I use. Each line sticks to what Google's docs say.
| The page | Do this | Why (Google's docs) |
|---|---|---|
| Gone for good, no close match | 404 or 410 | A 4xx removes the URL from the index and slows crawling of it |
| Replaced by a closely matching page | 301 or 308 to that page | A permanent redirect is a strong signal the target should be indexed. A 302 is a weak signal |
| Lots of old URLs, no close matches | 404 or 410, not one redirect to the home page | Many unrelated redirects to one page can count as a soft 404 |
| People still need it, but not in search | 200 with noindex | The page stays usable. It doesn't save crawling: Google still requests it, then drops it |
| An event or offer that ends on a date | Keep it live with unavailable_after | Google won't show it after that date and crawls the URL a lot less |
| A filter combination with no results | 404 at its own URL | Google's faceted navigation doc says return 404, not a redirect to a shared "not found" page |
Noindex is a tag that tells Google "don't show this page in search". Two traps catch most teams:
- Blocking a removed page in robots.txt. robots.txt is the file that tells crawlers where they can't go. If you block the page, Google can't fetch it, so it never sees the 404, 410 or noindex. Google says blocked URLs stay in the crawl queue longer.
- Leaving removed pages in the sitemap. The sitemap is Google's shopping list of URLs. If a dead URL is on it, you're inviting Google to keep crawling it. The exception is a site move, where Google suggests keeping the old-URL sitemap for a while so it finds the redirects.
Is a 404 permanent? Does Google drop a 410 faster?
A 404 doesn't say either way. The HTTP standard (RFC 9110) says a 404 "does not indicate whether this lack of representation is temporary or permanent", and that a 410 is preferred when the server knows it's permanent. So some guides that call a 404 "temporary" have it wrong.
Does Google drop a 410 faster? You'll find old quotes and small tests saying it can be a little quicker. Google's current status code doc doesn't make that distinction. It handles 404 and 410 the same way. I wouldn't plan around a difference.
How long until a removed page drops out of Google?
Google doesn't give a fixed time. A removed URL drops out when Google next crawls it and sees the 404 or 410. Pages Google visits often go first. Google's Page indexing help also says there's no way to make Googlebot forget a URL for good, but it will crawl it less and less often. You can watch progress in the Pages report.
How to check your removed pages by hand
You can do all of this with a terminal and a spreadsheet.
-
List the URLs and what each one should do. One row per URL: the URL, the intent (410, 404, 301 with a target, noindex, unavailable_after with a date, or 200 if it should stay live), and the target.
-
Check the status and the redirect chain. For each URL run
curl -sI -L <url>and read everyHTTP/line andlocation:line. The first status is what Google sees first. The last is where it ends up. Here's a 410 and a 404 side by side, which is all the "410 vs 404 example" most people need:curl -sI https://example.com/old-offer HTTP/2 410 curl -sI https://example.com/never-existed HTTP/2 404To return a 410 on purpose, most servers need one line. On nginx:
location = /old-offer { return 410; }. On Apache with mod_alias:Redirect gone /old-offer. On a CMS, look in its redirect or status settings, or ask your developer. Then run the curl check again. -
Look for soft 404 patterns. Does a "removed" URL return 200? Does it redirect to the home page? Both are wrong for a page that's meant to be gone.
-
Count the hops. Google's site move doc says keep chains short, ideally no more than 3 and fewer than 5. Googlebot follows up to 10 hops.
-
Check redirects are permanent. A 301 or 308 is a strong signal. A 302 or 307 is a weak one.
-
Check noindex where you chose noindex. Look for
noindexin thex-robots-tagheader or the robots meta tag. And check robots.txt doesn't block the URL. -
Check the sitemap. Search it for each removed URL. Anything still listed is a leftover.
What good looks like: every row returns exactly what you decided, in one hop or none, and nothing removed is still in the sitemap. What bad looks like: 200s on removed pages, redirects to the home page, 302s where you meant 301, chains of four or more, and sitemap leftovers.
How GONE makes it quicker
GONE runs the checks above for a list of URLs, each against its own intent. It's free and open, with no sign-in.
What you paste: one row per URL as url,intent,target. Intent is 410, 404, 301 or 308 (with a target), noindex, unavailable_after (date and time in the target column) or 200. You can set a default intent for rows without one, and add a sitemap URL or paste the sitemap XML.
Modes: Standard checks each URL against its own intent. Facet is for empty filter pages, so the default becomes 404. Post-event is for ended events, so the default becomes unavailable_after.
Two ways to run it:
- Full check (gone.py). A browser can't see redirect hops or most headers on other sites. So the full check is a small Python script you run on your own machine (gone.py v0.2, Python 3.8 or newer and the requests library). It writes gone-report.csv and gone-report.html. Import the CSV back into GONE.
- Quick check in browser (limited). It sees only the final status and URL. Some sites block it, and those rows show as Blocked.
How to read the result:
- Match: the server does what you intended.
- Warn: close enough, but worth a look. For example a 404 where you meant 410, or more than 3 redirect hops.
- Mismatch: it doesn't. Each one has a severity (High, Medium or Low) and a plain reason, such as "returns 200, intended 410 - soft 404 risk" or "still listed in sitemap".
- Blocked: the browser couldn't fetch it. Run gone.py.
Mismatches are grouped into fix groups, such as Still returns 200, Redirects instead of gone (home page), Redirect not permanent, Too many redirect hops and Still listed in sitemap. Copy mismatches as tickets, or download the results CSV.
Value, if you want it: GONE can put a worst, base and best monthly value on each fix group, from numbers you type in. The starting values are placeholders, not benchmarks. Replace them with your own, or skip this part. You can carry a fix group into PAYBACK.
Nothing you paste leaves the page except the URL checks you run.
Example (made-up numbers)
A site retires an old product range. The list has 40 URLs, all with intent 410, plus the sitemap URL.
- 31 return 410 in one hop. Match.
- 5 return 404. Warn. Fine to leave.
- 3 redirect to the home page. Mismatch, High: "redirects instead of gone (home page)".
- 1 returns 200. Mismatch, High: "returns 200, intended 410 - soft 404 risk".
- 6 of the 40 are still in the sitemap. Mismatch, High: "still listed in sitemap".
That's two tickets: fix the redirect rule and the one page still sending 200, and take the six URLs out of the sitemap. Then re-run the same list after the release.
What to do next
- Fix mismatches in groups, not one URL at a time.
- Re-run the same list after every release that touches redirects or templates.
- For redirect chains and host mix-ups, use DRIFT. For a full sitemap check, use LOCRA. For Search Console's Soft 404 and Not found rows, use RAUM.
- Removing thin pages as part of a manual action clean-up? Read how to write a reconsideration request before you file.
- Moving a whole site? See SEO migration services.
Sources
- HTTP status codes
- Crawl budget
- Page indexing report
- Crawl Stats report
- URL Inspection tool
- Site moves
- Faceted navigation
- RFC 9110 HTTP Semantics, section 15.5.5
- nginx return directive
- Apache mod_alias Redirect
- Robots meta tag
- WordPress core handle_404(), wp-includes/class-wp.php
- Changes to attachment pages (WordPress 6.4 dev note)