SmartJson.io
← All JSON error messages

Unexpected token '<': your code got an HTML page, not JSON

By Santhi · Messages captured October 9, 2026 on 11 runtimes · How we test

The parser read a < as the first character. JSON never starts with <, but every HTML page does. Your request reached something that answered with a web page, and the code passed that page to JSON.parse or response.json().

What each runtime prints

We ran this input through JSON.parse in each browser and Node version, and through json.loads in Python. These are the messages exactly as printed.

Input: An HTML 404 page
<!DOCTYPE html><html><body>Not Found</body></html>
RuntimeExact message
Chrome 151Node 24Node 22Node 20Unexpected token '<', "<!DOCTYPE "... is not valid JSON
Firefox 153JSON.parse: unexpected character at line 1 column 1 of the JSON data
Safari 26 (WebKit)BunJSON Parse error: Unrecognized token '<'
Node 18Unexpected token < in JSON at position 0
Python 3.13Python 3.12Python 3.10JSONDecodeError: Expecting value: line 1 column 1 (char 0)
  • Chrome and Node 20+ quote the start of what they got, so "<!DOCTYPE " or "<html><hea" in the message is the start of the page itself.
  • Python says "Expecting value: line 1 column 1 (char 0)". It says exactly the same for an empty body, so in Python you cannot tell the two apart from the message. Print the first 200 characters of the body.
  • Node 18 and older say "Unexpected token < in JSON at position 0", without quotes around the <.

Paste the response body (DevTools, Network tab, Response). It is checked in your browser and not sent anywhere.

Common causes

  1. 1

    A 404 page: the URL is wrong

    A typo in the path, a missing /api or /v1 prefix, or a base URL that points at the website instead of the API. The server answers with its normal "Not Found" page.

  2. 2

    A login page: the session expired

    The token or cookie expired, or the request was sent without it, so the server redirected to sign-in. fetch follows redirects without telling you: res.status is 200 and res.redirected is true.

  3. 3

    Your own app's index.html: the dev proxy is missing

    In a Vite, Create React App or Angular dev server, a request to /api/... that the proxy does not handle falls through to the single-page-app fallback, which serves index.html for every unknown path. The same happens on a static host with a "rewrite everything to index.html" rule.

  4. 4

    A proxy or CDN error page: the server behind it is down

    nginx, Cloudflare or a load balancer answers with its own 502, 503 or 504 page when the app behind it is down, restarting or too slow.

  5. 5

    A server error page: the app crashed

    Frameworks in debug mode return an HTML stack trace for a 500. The fix is on the server; its logs have the details.

How to fix it

Check the status and the Content-Type before parsing, and put the start of the body in the error. Then the error says which of the five pages you got.

JavaScript

const res = await fetch(url);
const text = await res.text();
const type = res.headers.get('content-type') ?? '';
if (!res.ok || !type.includes('application/json')) {
  throw new Error(`${res.status} from ${res.url}: ${text.slice(0, 200)}`);
}
const data = JSON.parse(text);

Python

r = requests.get(url, timeout=10)
if not r.ok or "application/json" not in r.headers.get("Content-Type", ""):
    raise RuntimeError(f"{r.status_code} from {r.url}: {r.text[:200]}")
data = r.json()
  • res.url is the address after redirects. If it ends in /login or /signin, the session is the problem, not the API.
  • In the browser, open DevTools, go to the Network tab, click the request and look at Response. You will see the page.

Related

  • Unexpected end of JSON input: an empty or cut-off body
  • "[object Object]" is not valid JSON
  • JSON Validator

How we tested: the messages above come from running each input through the real parsers (Chrome 151, Firefox 153, Safari 26 (WebKit), Node 24, Node 22, Node 20, Node 18, Bun, Python 3.13, Python 3.12, Python 3.10) on October 9, 2026. The script and inputs are listed on How we test.

Published October 9, 2026. Found a message that reads differently in your version? Tell us and we will add it.

All Tools & Converters

JSON Tools

  • JSON Hub
  • JSON Formatter
  • JSON Validator
  • JSON Repair
  • JSON Error Messages
  • JSON Viewer
  • JSON Minify
  • JSON Stringify
  • JSON Sorter
  • JSON Compare
  • JSON to CSV
  • JSON to XML
  • JSON to YAML

XML Tools

  • XML Hub
  • XML Formatter
  • XML Validator
  • XML Compare
  • SOAP Formatter
  • WSDL Formatter
  • XML to JSON
  • XML to CSV

CSV Tools

  • CSV Hub
  • CSV Formatter
  • CSV Validator
  • CSV to JSON
  • CSV to XML
  • Compare Tools

    • JSON Compare
    • XML Compare
    • YAML Compare
    • CSV Compare
    • Text Compare

YAML Tools

  • YAML Hub
  • YAML Formatter
  • YAML Validator
  • YAML to JSON
  • Other Tools

    • Converters Hub
SmartJson.io

JSON, XML, CSV and YAML tools that run in your browser. Nothing you paste is uploaded.

Sitemap

Company

  • About Us
  • Contact
  • How We Test
  • Changelog
  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • Disclaimer

© 2026 SmartJson.io. All rights reserved.

Report a problem with this page
Made withfor developers