Foundgrove
← All posts

SEO · 9 min read

Soft 404 Errors: Why Google Thinks Your Page Is Broken

Summary

Google flags a soft 404 when a page you think is fine looks empty to it. Here is how to see what Googlebot rendered — and which pages deserve a 410.

By Hyder Shah, Founder & CEO · Published July 13, 2026 · Updated July 13, 2026

You opened the Page Indexing report in Search Console and found a stack of URLs under Soft 404. You clicked one. It loads. It looks fine. Nothing is broken.

That is exactly the problem. A soft 404 is Google saying this page looks empty to me about a page you believe is working — and then quietly leaving it out of the index. No penalty, no warning, no ranking drop to investigate. The page just never shows up.

Most posts on this treat every soft 404 as a bug to fix. That is wrong. On a service-business site the flagged URLs split into two groups: pages that should be deleted properly, and pages that Googlebot genuinely cannot see. This post separates the two, then fixes both.

What is a soft 404, and why does Google call a working page broken?

A soft 404 is a URL that returns an HTTP 200 OK status code while its content looks like an error to Google. Search Console's Page Indexing report defines the status as: 'The page request returns what we think is a soft 404 response. This means that it returns a user-friendly not found message but not a 404 HTTP response code.' See the Page Indexing report documentation.

Google's HTTP status-code guidance says the same thing from the other side: when content suggests an error — an empty page, or an error message — despite a 2xx success status, Search Console will show a soft 404 error. Source: HTTP status codes and network errors.

There are two ways to end up here, and they need opposite fixes:

CauseWhat Google seesCorrect fix
The page is genuinely gone or emptyA 'no results' or 'not found' message served with a 200Return a real 404 or 410 and stop pretending the URL exists
The page has content, but not in the HTML Googlebot rendersA shell, a spinner, or a stubFix rendering or thicken the page — do not delete it

Get this backwards and you either delete a page you needed, or you spend a month 'improving' a page that should have been a 410 in the first place. So the first job is not fixing anything. It is looking at what Googlebot actually saw.

How do you see what Googlebot actually rendered on your page?

Use the URL Inspection tool in Search Console, run Test Live URL, open View Tested Page, and read the HTML tab — that is the rendered HTML, the version Google indexes after JavaScript runs. Google's JavaScript guidance says it plainly: use the Rich Results Test or the URL Inspection Tool to check if the rendered HTML has all the content you expect. Source: Fix Search-related JavaScript problems.

This is the whole diagnosis, and almost nobody does it. Looking at the page in your browser tells you nothing, because your browser runs your JavaScript, waits as long as it likes, and never gets rate-limited.

Run all four checks on one affected URL before you touch any code:

  • Check the status code. In URL Inspection, the live test shows the HTTP response. If it says 200 on a page that should not exist, you have found your soft 404.
  • Read the rendered HTML. Search the HTML tab for a sentence you can see on the page. If it is not there, Googlebot did not see it either.
  • Read the screenshot. URL Inspection shows what the rendered page looked like. A blank white box or a loading skeleton is the answer.
  • Check the raw HTML too. Fetch the URL with a plain HTTP request and no JavaScript. If the body is an empty div with a script tag, everything you rank on is being injected after the fact.

Whatever you find in that rendered HTML is the truth. Everything downstream — a technical SEO audit, a content rewrite, a redirect plan — is guesswork until you have run this once.

Is your JavaScript framework serving Googlebot an empty shell?

If your site is a single-page app, this is the most likely cause. Google's own documentation states that when a SPA uses client-side JavaScript to handle errors, it will 'often report a 200 HTTP status code instead of the appropriate status code,' and that 'this can lead to error pages being indexed and possibly shown in search results.' Source: Fix Search-related JavaScript problems.

The mechanism is worth understanding, because it explains why the problem is intermittent and why your developer swears the page works. Google processes JavaScript in three phases — crawling, rendering, indexing. Pages returning a 200 go into a rendering queue, and Google's guidance is explicit that a page 'may stay on this queue for a few seconds, but it can take longer than that.' Source: JavaScript SEO basics.

So the crawl and the render are two separate events. Between them, your URL is a shell with a 200 on it. If the render fails — a blocked script, a client-side data fetch that times out, a route your router does not recognise — the shell is all Google ever gets. That shell is a soft 404.

Client-side routing makes it worse. A React or Vue app with a catch-all route will happily serve a 'page not found' component at any URL an old sitemap, a stale backlink, or a bot invents — all with a 200. Now every garbage URL pointing at your site is an indexable error page. This is one of several reasons we favour server rendering or static generation for marketing sites: the status code is decided on the server, where it belongs.

Are your service-area pages thin enough to read as an empty state?

Yes, if the only unique content on the page is the town name. Google's recommended action for a soft 404 is direct: return a 404 for truly not-found pages, and add 'more information on the page to let us know that it is not a soft 404.' That second half is Google telling you the page is too empty to count as a page.

This is the quiet killer for plumbers, roofers, HVAC companies and law firms who bought a location-page package. Forty URLs get generated. Thirty-eight of them are the same 120 words with a different city dropped in, plus a map embed. To a crawler that has already seen thirty-seven of them, number thirty-eight carries nothing new.

The patterns that reliably trip this on service sites:

  • Templated city pages with one swapped variable and a stock photo — no local jobs, no pricing, no service specifics.
  • Empty listing pages — a 'jobs in Tulsa' or 'reviews' template that renders 'No results found' when the data set is empty, and returns 200 while doing it.
  • Booking or quote pages that are just an iframe — the widget is a third-party embed, so the crawlable HTML is a heading and nothing else.
  • Filter and pagination URLs — /services?area=none produces a valid-looking page with zero content and gets crawled forever.
  • Placeholder pages you shipped 'for later' — a coming-soon heading with a 200 status is the textbook soft 404.

The fix is not a tweak to the template. Either the page earns its existence — real service details, real pricing ranges, real proof, something specific to that city — or it gets removed. A page that exists only to hold a keyword is a page Google has already decided not to index.

When is a soft 404 actually good news?

When it lands on a URL you did not want indexed anyway — and on most service-business sites that is a large share of the list. Google has done your content audit for you, for free, and told you which URLs carry nothing.

Sort the affected URLs into three buckets before you write a single line of code:

BucketExampleAction
Dead — should not existAn old /promo/spring-2023 landing page, a deleted serviceReturn 410, remove from sitemap, kill internal links
Dead but replacedA retired service page with a live equivalent301 redirect to the closest real match, not the homepage
Alive but invisibleA service page Googlebot renders as a shell, a thin city pageFix rendering, or thicken the page until it deserves the index

Only the third bucket is engineering work. Buckets one and two are a morning's cleanup, and clearing them makes the report readable — which is the point. A Page Indexing report with 300 soft 404s that are all abandoned URLs is noise. Twelve soft 404s where three are your money pages is an emergency. Volume tells you nothing; which URLs tells you everything. The same triage logic applies to crawled - currently not indexed, which sits one shelf over in the same report.

What is the difference between returning a 404 and a 410 — and when do you use each?

Functionally, almost none — Google's status-code documentation groups them together and states that 'Google doesn't index URLs that return a 4xx status code, and URLs that are already indexed and return a 4xx status code are removed from the index.' For both, the documentation notes that crawling frequency gradually decreases. Source: HTTP status codes and network errors.

Anyone telling you a 410 gets you deindexed dramatically faster than a 404 is selling certainty Google does not offer. The honest difference is one of intent, and it matters for your own team more than for Google:

StatusMeansUse when
404 Not FoundThe URL is not found right nowThe page may return, or you are not sure it is permanent
410 GoneThe resource is deliberately and permanently removedYou killed the page on purpose and it is never coming back
301 Moved PermanentlyThe content lives at another URLThere is a genuine, close replacement page
200 OK with a 'sorry, not found' messageNothing — this is the bugNever

Verdict: use a 410 for pages you deliberately deleted and a 301 only when a real replacement exists. Do not redirect forty dead city pages to the homepage — Google routinely treats an irrelevant redirect as a soft 404 in its own right, which lands you straight back in this report. When in doubt on a migration, read what actually causes traffic loss after a redesign before you write the redirect map.

How do you fix a soft 404 in Next.js or another client-rendered site?

In Next.js, call notFound() on the server, before the response starts streaming. The Next.js docs state that invoking notFound() throws a 404 fallback error, renders your not-found file, and injects a robots noindex meta tag. Source: notFound() API reference.

The timing is the part everyone misses, and it is the reason a 'fixed' Next.js site keeps reporting soft 404s. Next.js documents that when a route streams, 'a 200 status code will be returned' and, because the response headers have already been sent, 'the status code of the response cannot be updated.' The docs go on: some crawlers may label these responses as soft 404s, though in the streaming case the page is explicitly marked noindex so it is not indexed. Source: loading.js — Status Codes.

Translation for a budget holder: if your not-found check runs after the page has started streaming — after a loading skeleton renders, or after an await that suspends — the HTTP status is locked at 200 for good. The Next.js guidance is to place notFound() before those Suspense boundaries and before any await that may suspend, or to check that the resource exists in the proxy layer if you need a genuine 404 status.

If you are on a framework Google cannot count on, Google offers exactly two sanctioned workarounds for SPAs — use them, in this order:

  • Use a JavaScript redirect to a URL for which the server responds with a 404 HTTP status code. The status code is real, so the URL leaves the index cleanly.
  • Add a robots noindex meta tag to error pages using JavaScript. Weaker — it depends on Google rendering the page — but it stops the error page being indexed.

Both are quoted from Google's JavaScript SEO basics. The first is the one to build; the second is the fallback when you cannot control the server response. Neither is a substitute for rendering your real content server-side in the first place — see our Next.js for marketing sites guide for the setup we recommend.

How do you stop soft 404s from coming back?

Make the status code a build-time decision, not a runtime accident — and check the rendered HTML every time you ship a new page template. Soft 404s recur because the two habits that cause them are cheap: shipping empty templates, and deleting pages by unlinking them instead of returning a real status code.

The routine that keeps the report clean:

  • Never ship a placeholder with a 200. No page goes live until it has content worth indexing. If it is not ready, it is not deployed.
  • Delete pages properly. 410 the dead ones, 301 the replaced ones, and remove both from the XML sitemap the same day.
  • Empty states return 404. A listing page with zero results is not a page — the server should say so.
  • Test one URL per new template in URL Inspection, reading the rendered HTML, before you generate forty more from it.
  • Re-check the Page Indexing report monthly and validate the fix in Search Console so Google recrawls the batch.
  • Sitemap hygiene: if a URL is in your sitemap and returns a soft 404, you are actively asking Google to crawl a page you have told it not to trust.

Expect the report to lag. Google recrawls on its own schedule — days to weeks — and no agency can shorten that. Anyone promising a fixed turnaround on a deindexation fix is guessing. What you control is whether the next crawl finds a real status code and real content.

If your soft 404s are concentrated on the pages you actually sell from, that is a rendering or template problem, not a content problem, and it will not fix itself. Our technical SEO service covers status-code auditing, rendered-HTML checks across every page template, and the redirect map for the pages that deserve to die. Get my free audit.

Where does this fit in your stack?

If you're running a US service business, the playbook in this post pairs with our full services lineup and applies cleanly across our supported industries and US locations. If you want help implementing it, book a free strategy call — we'll review your current setup and prioritize the next three moves.

For the deeper engagement details, see our SEO service. New to the terminology here? Our SEO & marketing glossary defines every acronym in this post.

Want this built for your vertical? See SEO for SaaS Startups, SEO for B2B Software Companies, SEO for Plumbing Companies, SEO for Law Firms, SEO for IT Services & MSPs.

What are the most common questions about this topic?

Common questions readers send us about this topic.

What causes a soft 404 error?

A soft 404 happens when a URL returns a 200 OK status code but its content looks like an error page to Google. Search Console defines it as a page returning a user-friendly not-found message without a 404 HTTP response code. The two common causes on service-business sites are pages so thin they read as empty — templated city pages, empty listings, placeholder pages — and JavaScript sites where Googlebot renders a shell instead of your content.

Does a soft 404 hurt my rankings?

It does something worse than hurt rankings: the page is not indexed at all, so it cannot rank for anything. There is no penalty and no site-wide damage — Google simply declines to include the URL. If the affected page is a service page, a city page, or a landing page you are paying to promote, that is a total loss of the asset. If the affected page is an abandoned URL you forgot about, it costs you nothing.

How do I check what Googlebot rendered on my page?

Use the URL Inspection tool in Google Search Console. Run Test Live URL, click View Tested Page, and read the HTML tab — that is the rendered HTML, the version Google indexes after JavaScript executes. Google's JavaScript documentation recommends using the URL Inspection Tool or the Rich Results Test to check whether the rendered HTML contains all the content you expect. Also read the screenshot: a blank box or a loading skeleton is your diagnosis.

Should I return a 404 or a 410 for a page I deleted?

Return a 410 if you deleted the page on purpose and it is never coming back; return a 404 if the URL might return or you are unsure. Practically, Google treats them almost identically — its documentation says URLs returning a 4xx status code are not indexed, and already-indexed URLs returning 4xx are removed from the index. Use a 301 redirect only when a genuinely equivalent replacement page exists, not to funnel dead pages to your homepage.

Can a JavaScript site cause soft 404s?

Yes, and it is one of the most common causes. Google's documentation states that when a single-page app uses client-side JavaScript to handle errors, it often reports a 200 HTTP status code instead of the appropriate one, which can lead to error pages being indexed. Client-side routing compounds it: a catch-all route will serve a not-found component at any invented URL with a 200 status, turning every bad link pointing at your site into an indexable error page.

Is a custom 404 page that returns 200 a soft 404?

Yes — that is the textbook definition. A branded not-found page is good for users, but the HTTP status code has to be 404 or 410, not 200. If your custom error page returns 200, every broken URL on your site becomes a crawlable, indexable page as far as Google is concerned. Check it directly: request a URL you know does not exist and look at the status code the server actually sends, not what the page looks like in a browser.

How do I fix a soft 404 in Next.js?

Call notFound() on the server before the response starts streaming. Next.js documents that notFound() throws a 404 fallback error, renders your not-found file, and injects a noindex robots meta tag. The catch: once streaming starts, a 200 status has already been sent and cannot be updated, so a not-found page rendered after a Suspense boundary keeps its 200. Place notFound() before any Suspense boundary and before any await that may suspend, or check the resource in the proxy layer.

Do soft 404s affect crawl budget?

They waste crawl activity on URLs that return nothing useful, which matters most on large sites with hundreds of generated pages. Google's status-code documentation notes that for URLs returning 404 or 410, crawling frequency gradually decreases — the point being that a real error status lets Google back off, while a 200 keeps the URL in rotation. A few soft 404s on a small site is not a crawl-budget crisis. Four hundred of them on a programmatic city-page build is.

About the author

Hyder Shah

Founder & CEO, Foundgrove

Hyder Shah is the founder of Foundgrove, an SEO and GEO agency for US service businesses. See our editorial policy for how these guides are researched and reviewed.

Related reading

Other tactical pieces from the Foundgrove blog.

Want help applying this to your business?

Book a free 30-minute call. We'll review your current acquisition stack and show you the three highest-leverage moves for your industry and state. Or read how our SEO service works.

Free SEO & AI visibility auditGet my free audit