Soft 404s: what they are, how to find them and how to fix them

Short answer

A soft 404 is a page that tells visitors it doesn't exist, or is nearly empty, while the server answers 200 OK. Google then has to work out from the content that it's an error. When it does, Search Console lists the page as "Soft 404" and leaves it out of results. The fix is to make missing pages return a real 404 or 410, redirect moved pages to their replacement, and give real pages enough content that they don't look empty.

What a soft 404 looks like

Visitors and search engines read two different things. People read the page. Crawlers read the status code first:

What visitors see the page
Sorry, that page can't be found

It may have moved or been removed.

Back to the shop
What the server says response headers
HTTP/1.1 200 OK  ← "this page is fine"
content-type: text/html; charset=utf-8
cache-control: max-age=600

A real missing page should start:
HTTP/1.1 404 Not Found

The words say "missing", the status says "fine". Google may spot the error from the words, or it may index an empty page.

A real 404 is clear-cut: Google doesn't index a URL that returns a 4xx status (404, 410 and the like), drops it if it was indexed, and crawls it less over time. A soft 404 depends on Google spotting the error from the content. It also won't show up in any report that lists broken pages by status code.

Where they come from

Not-found templates The CMS or framework shows a friendly "page not found" template but forgets to set the status, so it goes out as 200.
Single-page apps The server answers 200 for every URL and JavaScript shows a not-found view. See JavaScript SEO for Google's two fixes.
Discontinued products A product page that now says "no longer available" with nothing else on it.
Empty listings Category, tag or search pages showing "0 results", often generated by filters.
Catch-all redirects Every missing URL redirected to the homepage. Visitors don't find what they wanted, and Google's own help says not to redirect missing pages to your homepage.

What each page should return

SituationReturnWhy
Gone, no replacement404 or 410Tells search engines to drop it. 410 says it's gone on purpose, though Google treats 404 and 410 the same. Keep a helpful not-found page for visitors: the status and the design are separate.
Moved, or a close replacement exists301 to the replacementSends visitors and links on to the right place. Only redirect to a page that really replaces it.
Product out of stock for now200, with real contentKeep the details, say when it's back, and show alternatives, so the page is still worth indexing. Say "out of stock", not "no longer available", in the title and heading.
Empty listing that will fill again200 with noindex, or 404Keep it out of results until there's something to show.
Valid page that Google flags200, with more contentGoogle can mistake a very thin page for an error. Add the content the page is meant to have.

Thin pages

A page doesn't have to say "not found" to be read as one: an empty or nearly empty page can be flagged too. There's no official word count, but a main content area with only a few sentences deserves a look. Contact, login and basket pages are fine short. Pages meant to rank for something usually aren't.

How to check by hand

1Test what a missing page returns 30 seconds

The quickest test for a whole site: ask for a URL that can't exist. Open DevTools (F12) on any page of the site, go to the Console and paste:

// Asks the server for a page that can't exist, and shows the status it returns
const res = await fetch(location.origin + '/this-page-should-not-exist-' + Date.now(), { cache: 'no-store' });
const s = res.status;
console.log(s === 404 || s === 410 ? 'Good: missing pages return ' + s
  : s >= 400 && s < 500 && s !== 429 ? 'OK: missing pages return ' + s + ' (Google treats it like a 404, but 404 or 410 is clearer)'
  : s >= 500 || s === 429 ? 'Server error ' + s + ': not a soft 404, but fix the error first'
  : 'Soft 404: a missing page returned ' + s + (res.redirected ? ' after redirecting to ' + res.url : ''));

If it returns 200, or redirects to the homepage, missing URLs on your site are probably soft 404s. Try a made-up URL inside each section too, such as /products/not-a-real-product, because product and blog templates often handle missing items their own way. To find links that already lead to missing pages, see how to find broken links.

2Check a page that says it's missing 30 seconds

On a page you suspect, such as a discontinued product, paste:

// Checks this page: does it say "not found" while the server says it's fine?
const res = await fetch(location.href, { cache: 'no-store' });
const h1 = document.querySelector('h1');
const text = document.title + ' ' + (h1 ? h1.innerText : '');
const saysMissing = /(page|product|item|post)s? (not found|can['’]?t be found|cannot be found)|^not found\b|(does not|doesn['’]?t) exist|no longer (available|exists)|\b(error 404|404 error|404 not found|404 page)\b|^\s*404\s*$/i.test(text) || /^\s*404\b/.test(document.title);
console.table({
  'HTTP status': res.status,
  'Says it is missing': saysMissing ? 'yes' : 'no',
  Verdict: !saysMissing ? 'No not-found wording in the title or H1'
    : res.ok ? 'SOFT 404: says missing but returns ' + res.status : 'OK: returns ' + res.status,
});

It reads the page's title and first H1 for not-found wording, and checks the status the server sends.

It only looks for common English phrases in the title and first H1, so an article about 404 errors won't trip it, but neither will a page that just says "Oops!" or is empty. Check those yourself.

3Read the status in DevTools 1 minute

Open the Network tab, reload, and look at the Status column for the first row (the page itself). A not-found page should show 404, not 200.

4See what Google flagged 5 minutes

In Google Search Console, open Indexing → Pages and look for Soft 404 under the reasons pages aren't indexed. Open it to see example URLs, then decide for each one whether it's really missing (return 404 or 410) or real but thin (add content).

If Search Console lists the page as crawled but not indexed, see Crawled and Discovered, currently not indexed.

How crawlers report this

If a crawl sent you here, these are the labels to look for. Our guide to Screaming Frog and Sitebulb issues covers other common ones.

Screaming FrogSitebulbWhat it means
Content: Soft 404 PagesContains possible soft 404 phrasesThe page returns 200 but reads like an error or empty page.
Content: Low Content PagesNo direct matchThe page has little text. This is a prompt to look, not a fault in itself.

Doing this on every page?

SEOSnip spots soft 404s for you

Open the extension on any page and it compares what the page says with the status the server sent. You get:

  • A flag when the title or first H1 uses not-found wording such as "page not found", "product not found", "no longer available" or "error 404" while the status is 2xx, with the words highlighted
  • A flag when the main content (or the whole page, if there's no single <main>) has fewer than 200 words, as a prompt to look rather than a rule
  • A ticket with that evidence, and a "Check if fixed" button that re-runs the check after the change ships