Skip to Content

Page returns 404 but has content

What it is

The page answers with HTTP status 404 (Not Found), yet it shows real content: headings, paragraphs, products. Visitors see a normal page, while every crawler is told it does not exist. It often happens after a migration or routing change leaves the template rendering the page while the status stays 404.

Why it matters

Search engines drop pages that answer 404  from their index, however good the content is, and AI crawlers get the same 404. Links from other sites to the page stop passing value. Because the page looks fine in a browser, the problem often goes unnoticed until its traffic is gone.

How Asky checks it

When the server answers 404 with an HTML page, Asky counts the words of its visible text in the raw HTML, leaving out <script>, <style>, <noscript> and <template> contents. Menus and footers count. A 404 with 200 words or more is reported here; a shorter one is treated as a genuine error page and reported as a 4xx client error instead. Other statuses, including 410, never trigger this check. The page gets no other finding: its URL, title, content and other on-page checks are skipped. This is not what Google Search Console calls a soft 404 (a page that answers 200 but looks like an error), which Asky does not check.

Reported as an error with high severity.

How to fix it

  1. Open the page and check the status in your browser’s developer tools (Network tab) or with an HTTP status checker.
  2. If it is your real not-found page and only its menu and footer push it past 200 words, nothing needs fixing: mark the issue resolved.
  3. If the page should exist, fix the route or template so it answers with status 200. In a CMS this often means publishing the page again or restoring its URL.
  4. If the content moved, redirect the old URL to the new one with a 301, and update internal links to point to the new URL.
  5. If the page should be gone, remove the content and keep the 404, or answer 410 (Gone).

Example

https://example.com/pricing shows the full pricing table in the browser. Checking only the status code gives it away:

curl -s -o /dev/null -w "%{http_code}\n" https://example.com/pricing # 404 before the fix, 200 after

← Back to Response Codes

Last updated on