Fix: Unexpected token < in JSON at position 0
You called response.json() or JSON.parse(), and your application crashed with a SyntaxError pointing to position 0. Here is why it happened and how to fix it.
(Chrome, Node.js, Safari, Firefox)
What Does This Error Mean?
Valid JSON must begin with an opening curly brace ({), an opening square bracket ([), a double-quoted string, a number, a boolean, or null.
An opening angle bracket (<) at position 0 is the universal marker of an HTML document (like <!DOCTYPE html> or <html>). You thought your API returned JSON, but the server actually returned an HTML page.
The 4 Most Common Causes
A typo in the endpoint path or a missing /api/ prefix caused your web server (Nginx, Apache, Next.js, Cloudflare) to serve your website's 404 HTML fallback page.
An unhandled exception crashed your backend application. Instead of returning an application error JSON payload, the reverse proxy rendered a generic server error HTML page.
An expired session cookie or missing Authorization Bearer token caused an auth gateway to redirect your request to an HTML login page.
In React/Vue/Vite projects, requesting an invalid route often serves index.html so client-side routing can take over. When your fetch calls a non-existent API route, it gets your app's main HTML.
How to Defend Your Code
Never call response.json() blindly without verifying the HTTP status and content type header:
const data = await fetch('/api/user').then(r => r.json());
// Good: Defensively verify status & content type
const res = await fetch('/api/user');
const contentType = res.headers.get('content-type') || '';
if (!res.ok) {
const errorText = await res.text();
throw new Error(`HTTP ${res.status}: ${errorText.slice(0, 100)}`);
}
if (!contentType.includes('application/json')) {
throw new Error(`Expected JSON but received ${contentType}`);
}
const data = await res.json();
Frequently Asked Questions
What causes 'Unexpected token < in JSON at position 0'?
This error occurs when JavaScript calls JSON.parse() or response.json() on a response that starts with an opening angle bracket (<). This almost always means the web server returned an HTML webpage (such as a 404 Not Found page, 500 Server Error, or a login/redirect page) instead of a JSON payload.
How do I safely inspect an API response before parsing JSON?
Check response.ok and response.headers.get('content-type') before calling response.json(). If the content-type is 'text/html', inspect response.text() to read the error message returned by the server.
Why does QuietJSON flag HTML error pages?
When developers paste API responses into JSON tools, generic parsers just say 'Unexpected token <'. QuietJSON immediately identifies <!DOCTYPE html> or HTML tags and warns you that your API returned an HTML error document.
Inspect payloads with QuietJSON Formatter
Get immediate diagnostics when API responses contain unexpected HTML or broken tokens.