sfw/fix
NOT_HTML high

Lighthouse/PageSpeed error "NOT_HTML"

The URL returned a non-HTML content type, so Lighthouse refused to audit it as a web page.

What you see

The provided URL does not have a valid HTML document. (NOT_HTML)
Lighthouse can only audit pages that return text/html.

What’s actually happening

You submit a URL and PageSpeed Insights rejects it before any metrics run. The page may render fine in a browser because the browser sniffs content or follows a download, but Lighthouse strictly checks the Content-Type header on the final response. Anything that isn't text/html gets refused.

Common causes

  • The URL is an API endpoint returning application/json or application/xml
  • The server sends Content-Type: application/octet-stream or attachment disposition, triggering a download instead of a render
  • A PDF, image, or feed (RSS/Atom) URL was submitted by mistake
  • Content negotiation serves a different type to bots — the server reads Lighthouse's User-Agent or Accept header and returns JSON or a 406
  • A misconfigured server omits the Content-Type header entirely, or sets it to text/plain, so Chrome doesn't treat the response as a document

How to fix it

  1. Inspect the response headers directlycurl -sI https://example.com/page | grep -i content-type. If it isn't text/html (with optional charset), that's the problem. Compare what the server returns to a browser versus to curl — a difference means content negotiation is in play.
  2. Fix the Content-Type the server emitsFor an HTML page mis-typed as text/plain or octet-stream, correct the MIME mapping. In nginx, check the types block or add default_type text/html; in Apache, verify AddType/ForceType. Make sure no Content-Disposition: attachment header is set on the page route.
  3. Submit the right URLIf you accidentally pointed PageSpeed at /api/data.json or a .pdf, audit the actual HTML page that links to it instead. Lighthouse has nothing to measure on a raw data response.
  4. Stop serving alternate content to the audit UAIf a CDN, WAF, or framework returns JSON/406 based on User-Agent or Accept, whitelist Chrome-Lighthouse. Test the bot path: curl -A "Chrome-Lighthouse" -sI https://example.com. If that returns JSON while a normal request returns HTML, your negotiation rule is the cause.
  5. Add a charset and confirm the final responseSet Content-Type: text/html; charset=utf-8 explicitly. If the URL redirects, check the Content-Type of the final 200 in the chain (curl -sIL), not the redirect itself — Lighthouse audits where you land.

Stop it recurring

Keep audited routes returning Content-Type: text/html; charset=utf-8 and never apply bot-based content negotiation to them.

Related errors