Guide

Soft 404 errors, or when your server and your page disagree.

A soft 404 is Google telling you that a URL returns a success status while the page itself looks like nothing is there. The server says 200, the content says empty, and Google believes the content. It is one of the few statuses where the fix is genuinely mechanical, once you work out which of five patterns you have.

Mechanical, once diagnosedFive patternsThe right status code for each

What Google is actually objecting to

Every URL returns an HTTP status code. 200 means here is the page you asked for. 404 means it does not exist. 410 means it existed and is deliberately gone. A soft 404 is the mismatch: the header claims success, and the page says "no results found" or "this product is no longer available" or is simply near-empty.

Google flags it because a site full of 200s that are really missing pages wastes crawl effort and pollutes the index. It is one of the few judgements Google makes about your content that has an unambiguous technical remedy, which is why it is satisfying to fix.

Test it in one command

Fetch the URL and look at the status line. If you see 200 on a page that a human would describe as empty, missing or "nothing here", you have your answer.

# what status does the server actually return?
curl -sI https://example.com/missing-page/ | grep -i '^HTTP'

# and does the body admit there is nothing there?
curl -s https://example.com/missing-page/ | grep -iE 'no results|not found|no longer available|out of stock'

The rule

The status code has to agree with the page. If a human would say the content is missing, the server must say so too. Everything below is a variation on that one sentence.

The five patterns

1. A custom error page returning 200

The classic. Someone builds a friendly "Sorry, we could not find that" page and wires it up so it renders at any unmatched URL, returning 200 because nobody set the header. Every mistyped link on the internet now creates an indexable page on your site. Return a genuine 404 with that page.

2. Empty search and filter results

Internal search pages and filter combinations with no matches: "0 results for…" at 200. On a store these multiply endlessly. These should generally not be crawlable at all, and where they are, an empty result set should return 404 rather than a successful empty page.

3. Discontinued products and expired listings

A product page kept alive after the product is gone, showing a stub. If the item is genuinely never coming back and nothing replaces it, 410 is the honest answer. If a successor exists, redirect to it. If it is temporarily out of stock, keep the page, keep the content, and say so on the page rather than emptying it.

4. Thin pages Google has decided are empty enough

A page with a heading and two sentences can be read as having no content. This one shades into a different status, and if the page genuinely should exist the answer is to make it worth indexing rather than to change a header. That is the territory of crawled, currently not indexed.

5. Content that only exists after JavaScript runs

If the served HTML is an empty shell and the content arrives via JavaScript, Google can capture the page in the empty state and record a soft 404. The fix is server rendering or prerendering for the content that matters, not a status code change. Fetching the raw HTML with curl, as above, shows you exactly what the crawler saw first.

Choosing the right status code

  • 404 for pages that do not exist, including empty search results and unmatched URLs. Nothing is lost by using it correctly.
  • 410 for content deliberately removed and not returning. Google treats it as a stronger signal than 404 and tends to drop the URL faster.
  • 301 when a genuine equivalent exists. Not the homepage. A redirect to a page that does not answer the same need is its own problem, and on a large scale Google may treat it as a soft 404 anyway.
  • 200 only when there is genuinely something there worth reading.

The temptation with a lot of expired URLs is to redirect them all to the homepage or a category. It clears the report and it is the wrong instinct: it tells Google the homepage is the equivalent of hundreds of specific pages, which it plainly is not. Where a real successor exists, redirect. Where it does not, let the page be gone properly. Getting this right at scale is a large part of what migration work actually involves.

The checklist

  • Fetch the URL and compare the status line to what the page actually says.
  • Confirm your custom error template returns 404 rather than 200.
  • Make empty search and filter results return 404, and keep them out of the crawl where possible.
  • Decide per removed item: successor exists means 301, gone for good means 410.
  • Check the raw HTML rather than the rendered page, in case the content depends on JavaScript.
  • Never blanket-redirect expired URLs to the homepage.

Book me

Getting soft 404s you cannot place?

Send us two or three of the flagged URLs. We will tell you which of the five patterns each one is and the status code it should be returning instead.

Reply within one working day No obligation Your details stay with us

Takes about 60 seconds. No newsletter and no CRM sequence. Your details are used to reply to this enquiry and nothing else. See the privacy notice.