{FormJSON}
Developer Troubleshooting Guide • API & JSON Debugging

How to Fix "Unexpected token < in JSON at position 0"

The ultimate guide to diagnosing why JSON.parse(), fetch(), and axios crash on HTML error responses.

Need to validate or format your API payload?
Test, inspect, and safely format your JSON payloads with zero server transmission.
Open JSON Validator →

01. Understanding the Error

When JavaScript throws SyntaxError: Unexpected token '<', ", it means your program attempted to execute:

JSON.parse("<!DOCTYPE html><html>..."); // 💥 CRASH: Character 0 is '<'

JSON documents must begin with an object brace {, an array bracket [, a string ", a number, a boolean, or null. The character < is never valid at position 0 in JSON.

02. Top 4 Reasons Your API Returns HTML

1. Incorrect URL or 404 Route

The endpoint path is misspelled (e.g. /api/users vs /api/user), causing the web server to return a 404 HTML page.

2. Server Crash (500 Error)

An unhandled backend exception caused the server framework (Express, Django, Laravel, Rails) to render an HTML stack trace.

3. Cloudflare or CDN Challenge (502 / 503)

A reverse proxy or WAF intercepted the request and returned a Cloudflare bot check, rate limit, or gateway timeout HTML page.

4. SPA Fallback / Catch-all Route

In React/Vue/Vite SPAs, unconfigured API proxy rules cause the dev server to return index.html for all requests.

03. Production-Ready Fix (JavaScript & TypeScript)

Always inspect response.ok and verify the Content-Type header before calling response.json():

async function safeFetchJson(url, options = {}) {
  const response = await fetch(url, {
    headers: {
      'Accept': 'application/json',
      ...options.headers
    },
    ...options
  });

  const contentType = response.headers.get('content-type') || '';
  
  if (!response.ok || !contentType.includes('application/json')) {
    const rawText = await response.text();
    console.error('Server returned non-JSON response:', rawText.slice(0, 300));
    throw new Error(`HTTP ${response.status}: Expected JSON, received ${contentType || 'unknown format'}`);
  }

  return await response.json();
}

Frequently Asked Questions

FAQ

What causes 'SyntaxError: Unexpected token < in JSON at position 0'?
This error occurs when your code expects JSON but receives HTML instead. The '<' character is the opening bracket of an HTML tag (such as '<!DOCTYPE html>' or '<html>') returned by a server error page (404, 500, or 502 Bad Gateway).
How do I see what the server actually returned instead of JSON?
In browser JavaScript, read the response as text using 'const text = await response.text()' before parsing, or inspect the Network tab in Chrome DevTools to view the raw response payload.
Why does this happen with fetch() or Axios in React/Next.js?
If your API route returns a redirect, 404 route mismatch, or unhandled server crash, the framework sends back an HTML error page. Calling 'response.json()' fails because HTML cannot be parsed as valid JSON.
How can I prevent this error in production?
Always check 'if (!response.ok)' or inspect the 'Content-Type' header ('application/json') before calling 'response.json()'.

Explore Related Tools & Converters

100% Client-Side