A soft 404 is an error that answers 200, so Google guesses

30/07/2026 · Laurent HTTP status codes
A soft 404 is an error that answers 200, so Google guesses

A soft 404 is a page that tells a person it is missing and tells a machine it is fine. The body says the content could not be found. The status line says 200 OK. Both are shipped in the same response, and they contradict each other.

Google reports these in Search Console, under Page indexing, with that exact label. What the label means is worth stating plainly, because it changes how you should feel about it: Google is telling you it read your page, disbelieved the status code, and made a judgement call. It had to. You gave it two answers and it could only use one.

The guess goes wrong in both directions

Most writing on this treats a soft 404 as a report of your mistake. Half the time it is, and the other half it is a false positive that costs you a page you wanted indexed.

The detection is heuristic, because it cannot be anything else. Short body, wording that resembles an error, near-identical content across many URLs, no meaningful links out. Those signals also describe several kinds of perfectly legitimate page.

A location page for a small business with three lines of address and a map. A product variant page that differs from its siblings in one field. A category page that currently holds two items because it is seasonal. A search results page that legitimately returned nothing this week. None of those is an error, all of them can be classified as one, and the report gives you no way to argue.

So the response depends on which direction you are in, and you have to look before you act. If the page really is a missing page dressed as a success, fix the status. If the page is real and thin, the status is already correct and the fix is content: something on that page has to be worth the visit, or the page should not exist as a separate URL.

Where they come from on client sites

Four generators, in rough order of how often I have found them.

The client-side router. The server is configured to answer every unknown path with index.html, which is exactly right for the application and makes a correct status impossible. The framework then renders a "not found" view in the browser, after the response. Every non-existent URL on the site is a 200. This one cannot be fixed in the front-end code, only in the server or edge configuration, which is why it survives so long: the team that notices it is not the team that can change it.

The plugin that catches too early. A page builder, a redirect manager, or a membership plugin intercepts the request before the CMS has decided the URL does not exist, and renders a template. The template contains the words "page not found", so a human reviewing the site sees the correct behaviour and moves on.

The empty archive. A tag with no posts, a category emptied by a bulk edit, a shop filter combination with no products. The page is real, the template renders, the status is genuinely 200, and there is nothing on it. Multiply by every facet combination and you have thousands of near-identical URLs.

The redirect to the homepage. Sending every dead URL to the root is treated as a soft 404 anyway, so it buys nothing and loses the chance to tell the visitor what happened. The four possible combinations of status and page, and why three of them are wrong, are laid out in the 404 page and the 404 status.

Finding them without waiting for Search Console

Search Console tells you weeks later, on a sample, for pages Google happened to crawl. You can ask the question directly and get the answer now.

curl -sS -o /tmp/body -w '%{http_code}\n' https://example.com/definitely-not-a-page-8817
wc -c /tmp/body
grep -icE 'not found|introuvable|nothing here|404' /tmp/body

A 200 in the first line and a match in the third is a soft 404, with no ambiguity and no waiting. Run it once per client site at handover and write the answer in the inventory.

For the empty-archive case, the test is different, because the URL is supposed to exist. Pick the element that proves the page did its job: the first product card, the article list, the price block. Then check that it is there.

curl -sS https://example.com/category/tools | grep -qF 'class="product-card"' && echo present || echo MISSING

The bigger family this belongs to

A soft 404 is one member of a class: responses where the status code is a claim rather than evidence. Once you start looking, the class is large.

A shop whose product feed failed overnight, rendering the grid with zero items. A page that arrives with its stylesheet missing, so every element stacks in a single column at full width. A database error message printed into the body by a host that returns 200 with it. A page rendered entirely by JavaScript that fails on a syntax error, leaving an empty container. Every one of those is a broken page for the visitor and a healthy line in an uptime report.

This is the thing our own tool exists to catch, and since it is our product I will say precisely what it does rather than gesture at it. It reads the body of the response and looks for two families of trouble: text patterns that mean a database or fatal error was printed into the page, and layout signals that mean the stylesheet did not arrive. The counts are in the repository, which is public and MIT licensed, so they can be recounted rather than believed: 41 error signatures in src/Check/Database.php, 9 layout signals in src/Check/Css.php.

None of that requires our tool. Any checker that lets you assert on body content will do the job, and if yours does not, a cron job with the two curl commands above will. What matters is the shift: stop asking whether the site answered, start asking whether it answered with the page.

The number that keeps this problem alive

Availability reports are computed from status codes, so a site that soft-404s every product page for a fortnight reports as fully available. The client reads the report, sees a green figure, and has no reason to ask.

That is not a reporting bug, it is the reporting doing exactly what it was built to do with the only input it was given. Which of the codes are worth an alert, which are worth a counter, and which mean nothing at all until you read the body, is the whole of the nine that matter in production.

Share this post.
Stay up-to-date

Subscribe to our newsletter

Don't miss this

You might also like