How to Fix Soft 404 Errors on Thin or Empty Pages
Soft 404s on thin pages — empty category filters, zero-result search pages, sparse location pages — need a different fix than a broken template. Here's the practical playbook.
When a soft 404 is caused by thin content rather than a broken template, you have three real options: populate the page with genuine content, redirect it to a populated parent, or make it return a real 404/410 when there's nothing to show. Which one is right depends on whether the page could ever have content worth indexing — not on making the error message disappear.
Not every soft 404 is a bug. A lot of them are pages that are technically working exactly as built — they just don't have anything on them. A product filter with zero matches, a location page for a city you don't actually serve yet, an internal search with no results: the server correctly returns 200 OK, and Google correctly reads the page as empty and files it as effectively a 404.
The general soft 404 guide covers all three causes. This one is the playbook for just this case — because the fix isn't a code patch, it's a content or architecture decision, and picking the wrong one either buries a page that should exist or keeps indexing pressure on pages that never will.
First, confirm it's genuinely thin — not a rendering problem
Before treating this as a content issue, rule out the other common soft-404 cause: a JavaScript-heavy page that Google renders as an empty shell even though it looks fine to you in a browser. In URL Inspection, click View Crawled Page → Screenshot (what Googlebot rendered) and compare it to what you see visiting the URL normally. If Googlebot's version is blank but yours isn't, that's a rendering gap, not a thin-content problem — the fix there is server-side rendering or a rendering solution, not more content.
If both versions genuinely show little or no content, you're in the right place.
The three real options
Every thin-page soft 404 resolves to one of these. The decision isn't about which is easiest — it's about what the page is actually for.
- Option 1 — Give it real content, if it should exist
For pages that have genuine long-term value once populated: a new city's location page before you have local reviews yet, a product category waiting on inventory, a seasonal page ahead of season. If the page's purpose is legitimate and durable, the right fix is writing real content for it now rather than waiting for it to "fill itself in" — Google won't index it in the meantime, and an empty page sitting live provides nothing to anyone who lands on it either.
Minimum bar: enough unique text, structure, or product data that a visitor gets value from the page even at its current, unpopulated state. A category page with zero products should still explain what belongs there and link to adjacent categories — not just show an empty grid.
- Option 2 — Redirect it to a populated parent
For narrow combinations that will rarely or never have content of their own — a filter combination like
?color=red&size=17that's almost never going to return results, a discontinued product variant. Redirect (301) to the nearest page that does have relevant content: the parent category, or the base product page. This consolidates any residual value into a page that's actually useful, instead of leaving a dead end live.Don't redirect broadly matching, commonly-searched combinations that just happen to be empty right now — those are Option 1 candidates, not Option 2. Reserve the redirect for combinations unlikely to ever justify their own page.
- Option 3 — Return a real 404 or 410
For pages with no plausible future value and no sensible parent to redirect to: a one-off internal search query with zero results, a truly discontinued product with nothing comparable in the catalog. Make the server return an actual
404 Not Found(or410 Goneif you're certain it's permanent) instead of200 OK. This is the fix that removes the soft-404 confusion entirely — you're telling Google plainly "this doesn't exist," which it can act on immediately, instead of leaving it to guess from a thin, technically-live page.
Implementing each by platform
WordPress / Shopify (category, tag, or collection pages with zero items): most themes render an "empty state" with 200 OK by default. To 404 instead when a collection or archive has no items, this typically requires a template-level check (is_archive() && !have_posts() in WordPress, or a Liquid conditional in Shopify's collection template) that renders your theme's 404 template instead of the empty grid. Redirecting instead is usually simpler — set up a rule that sends known-empty filter combinations to the parent category.
Next.js / React (dynamic routes, filtered or searched views): in a server component or route handler, check whether your data fetch returned results before rendering; if not, call notFound() (App Router) to return a real 404, or redirect via redirect() to a populated parent route. Don't let the page render an "empty state" UI with a 200 status for URLs you don't want indexed — that's the exact soft-404 pattern.
Webflow (CMS collection pages, empty filters): Webflow's native filtering is largely client-side, which itself can produce a soft-404-prone pattern — Google sees the unfiltered 200 page behind the filter UI. For genuinely empty CMS collection states, use the collection list's built-in "Empty State" element to at least render clear, real content (not a blank grid) rather than trying to force a true 404, since Webflow doesn't give you server-level status control per filter combination.
How to verify it's fixed
- Re-check what Google renders
URL Inspection → Test Live URL → View Tested Page. Confirm the rendered HTML now shows real content (Option 1), correctly redirects (Option 2), or the response is a genuine non-200 status (Option 3).
- Request indexing, once
Only after the fix is live. This nudges a recrawl; it doesn't override anything if the underlying fix isn't actually there yet.
- Watch the Pages report
Give it days to a couple of weeks. The URL should move off the "Soft 404" bucket in Pages → Why pages aren't indexed, and — for Option 1 pages — start showing impressions in the Performance report as Google indexes the now-substantive content.
When to leave it alone
If the affected URLs are low-value combinatorial pages you never wanted indexed in the first place (extreme filter permutations, expired promo pages, internal search result URLs), the soft-404 status isn't actually costing you anything — Google correctly isn't indexing junk. In that case the better move is often just to noindex and stop worrying about the count in this report, rather than spending engineering time forcing every one of them into a "correct" 404.
Sorting which thin pages deserve real content, a redirect, or a 404 — versus which ones don't matter at all — is the tedious part. TurboConsole connects to your Search Console account, tells you which soft 404s are actually costing you traffic and which are safe to ignore, and checks again every week. Percy doesn't rewrite your pages for you — he tells you exactly what to change and where. Sign in to connect Search Console.
Frequently asked
Should every empty category or filter page return a 404?
Is it better to noindex thin pages or fix the content?
Will thin pages ever recover once I add content?
What's the difference between fixing this and fixing a regular soft 404?
We surface these issues automatically.
Connect Search Console once. Every issue like this gets ranked by impact, with a fix you can ship today.
Related issues
- Soft 404 Error: What It Means + How to Fix It“Soft 404” in Google Search Console means a page returns a 200 OK status but looks empty or missing to Google. Here's why it happens and exactly how to fix it.
- Submitted URL Not Found (404): What It Means + How to Fix It“Submitted URL not found (404)” in Google Search Console means you submitted a URL that returns a 404. Here's why it happens — and exactly how to fix it.
- Crawled – Currently Not Indexed: What It Means + How to Fix It“Crawled – currently not indexed” in Google Search Console means Google saw your page but chose not to index it. Here's why it happens and exactly how to fix it.