QuietJSON
API & Parsing Error

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.

SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON
(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

1. Incorrect API URL (404 Not Found)

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.

2. Server Crash or 500 Internal Server Error

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.

3. Authentication Redirects (302 Found)

An expired session cookie or missing Authorization Bearer token caused an auth gateway to redirect your request to an HTML login page.

4. Single Page App (SPA) Fallback

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:

// Bad: Crashes with SyntaxError if status is 404 or 500
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.

Open Formatter →