404 error handling and soft 404
What the server answers for an address that does not exist. It has to be a 404: a missing page that answers 200 gets indexed as a real one.
When someone asks for a page that does not exist, the server must say so with HTTP 404 (or 410 for “gone for good”). The error page can look however you like — friendly text, a search box, links home — but its status code has to be an error. When a missing page answers 200, that is a “soft 404”: search engines treat it as a real page, index thin duplicates of your error screen, and spend crawl budget on addresses that should not exist. Monitoring tools also miss broken links, because every URL appears to work.
How SiteScan checks it
The scanner requests a random path that cannot exist on the site and reads the status of the final answer:
- green: 404 or 410;
- amber “Soft 404”: a 2xx status — including a redirect to the home page that ends in 200;
- amber with a status code: anything else, for example 500 or 403, which tells crawlers the server is broken or forbidding access rather than that the page is missing.
How to fix
Make the catch-all route return a real 404 status: in nginx error_page 404 /404.html;, in a single-page app let the server or the framework set the status for unknown routes instead of always serving index.html with 200. Do not redirect unknown addresses to the home page. Background and edge cases are in the article on soft 404 errors.
See this check on your own site
Run a free scan: the report shows this row for your domain along with the other checks of the site audit.
More in “Addresses & redirects”
What SiteScan checks
TLS certificate
- TLS certificate expiry
- Outdated TLS versions (TLS 1.0/1.1)
- TLS certificate chain
- TLS certificate issuer
- Certificate signature algorithm
Domain registration
- Domain registration expiry
- Registered domain name
- Domain registrar
- Domain registration date
- Domain last updated date
- Domain status codes (EPP)
- Domain transfer lock
- Registrar abuse contact
- RDAP and WHOIS data source
Indexing
- robots.txt file
- CSS and JS blocked in robots.txt
- XML sitemap
- Sitemap index file
- Off-domain URLs in the sitemap
- Sitemap lastmod dates
- Broken URLs in the sitemap
- RSS and Atom feed
Addresses & redirects
Security headers
- HTTP security headers and grade
- Strict-Transport-Security (HSTS) header
- Content-Security-Policy (CSP) header
- X-Content-Type-Options: nosniff
- X-Frame-Options and clickjacking
- Referrer-Policy header
- Permissions-Policy header
- HSTS preload list
- CORS and cross-origin reads
- HTTP TRACE method
Delivery & reputation
- Cache-Control header for HTML
- ETag and Last-Modified revalidation
- HTTP/3 and QUIC support
- Server version disclosure in headers
- DNS blocklist (DNSBL) check
Internal links
Exposure
- Exposed sensitive files (.env, .git, backups)
- Directory listing enabled
- Public JavaScript source maps
- Exposed WordPress endpoints
Well-known files
- security.txt file
- llms.txt for AI assistants
- llms-full.txt file
- ads.txt authorized sellers file
- humans.txt file
- Well-known change-password URL
DNS & email
- MX records (mail servers)
- SPF record
- DMARC record and policy
- DNSSEC signing
- CAA record
- Nameserver redundancy
- IPv6 support (AAAA record)
- MTA-STS policy
- TLS-RPT reporting record
- BIMI record (brand logo in email)
- Wildcard DNS record
- Dangling CNAME and subdomain takeover
Privacy & consent
- Analytics and tracking scripts
- Cookie consent banner
- Privacy policy link
- Terms of service link
- Imprint (Impressum)
- Accessibility statement
Core Web Vitals
- Lighthouse performance score
- Largest Contentful Paint (LCP)
- Cumulative Layout Shift (CLS)
- Interaction to Next Paint (INP)
- CrUX field data vs lab data