JSON Errors / JavaScript
Unexpected token < in JSON at position 0How to Fix: Unexpected token < in JSON at position 0
This error means JSON.parse() received a string starting with the character "<" - and JSON can never start with "<". In almost every case, your code expected JSON but actually received HTML: an error page, a login redirect, or a 404 page from the server.
The "position 0" part tells you the very first character is wrong, which rules out a typo inside your JSON. The problem is the response itself, not your parsing.
Common causes
1. The API returned an HTML error page
A 404, 500, or gateway error often returns an HTML page like "<html><body>404 Not Found...". Calling response.json() on it fails at the first character.
<!DOCTYPE html>
<html><head><title>404 Not Found</title>...2. Wrong URL or route
A typo in the endpoint path means your web server serves the SPA fallback page (index.html) instead of the API response - so you parse your own app shell as JSON.
3. Authentication redirect
An expired session can cause the server to respond with the HTML login page (often with a 200 status), which then fails to parse as JSON.
How to fix it
const res = await fetch("/api/data");
if (!res.ok) {
throw new Error(`HTTP ${res.status}: ${await res.text()}`);
}
const contentType = res.headers.get("content-type") ?? "";
if (!contentType.includes("application/json")) {
throw new Error(`Expected JSON, got ${contentType}`);
}
const data = await res.json();const res = await fetch("/api/data");
const raw = await res.text();
console.log(raw.slice(0, 200)); // ...an HTML error page? wrong route?Frequently asked questions
Why does it say position 0?
Position 0 is the first character of the input. JSON must start with {, [, a quote, a digit, or the literals true/false/null - "<" is invalid immediately, so parsing stops before reading anything else. It is the signature of receiving HTML instead of JSON.
The endpoint works in my browser - why does fetch fail?
Your browser session may be authenticated while your fetch call is not (missing cookies or Authorization header), so the server returns a login or error page to your code. Compare the raw response text with what the browser shows.
How do I see the actual response that failed?
Use res.text() instead of res.json() and log the first few hundred characters, or check the Network tab in DevTools. The response body will show you exactly what HTML came back and usually why.
Last updated:
Related JSON errors
You might also need
Free and in-browser, like everything on JSON Console. Browse all tools →