Definition: What is "Unexpected token < in JSON at position 0" Error?
"Unexpected token < in JSON at position 0" is a JavaScript error that occurs when you try to parse HTML as JSON using JSON.parse() or response.json(). The error happens because HTML starts with the < character (from tags like <html>, <body>), which is not valid JSON syntax.
This error typically occurs when an API endpoint returns an HTML error page (like a 404 Not Found page, 500 Internal Server Error page, or CORS error page) instead of the expected JSON response. When your code tries to parse this HTML as JSON, JavaScript throws the "Unexpected token" error because HTML is not valid JSON.
The error is common in web development when making API requests with fetch() or axios, especially when API endpoints are incorrect, servers return error pages, Content-Type headers are wrong, or CORS issues occur. Understanding and fixing this error is essential for robust API integration and error handling.
Key Point: "Unexpected token < in JSON at position 0" occurs when trying to parse HTML as JSON. This happens when APIs return HTML error pages instead of JSON responses. The solution is to check Content-Type headers, verify API endpoints, and handle errors properly before parsing.
What: Understanding the Error
The "Unexpected token < in JSON at position 0" error involves several components:
HTML Error Pages
When APIs encounter errors (404, 500, CORS), servers often return HTML error pages instead of JSON. These HTML pages start with <html> or <!DOCTYPE html>, which causes JSON parsing to fail. HTML error pages are default server responses, not API responses.
Example: API returns <html><body>404 Not Found</body></html> instead of {"error": "Not found"}
Wrong Content-Type Header
APIs should return Content-Type: application/json for JSON responses. When servers return Content-Type: text/html, browsers and code expect HTML, but if you try to parse it as JSON, you get the error. Wrong Content-Type headers are common in misconfigured APIs.
Example: API sets Content-Type: text/html but returns JSON, or vice versa
API Redirects
When APIs redirect (301, 302) to HTML pages (like login pages, error pages), the final response is HTML, not JSON. Fetch API follows redirects automatically, so you might get HTML from a redirect instead of JSON from the original endpoint. Redirects to HTML pages cause JSON parsing to fail.
Example: API redirects to /login.html or /error.html instead of returning JSON
JSON Parsing
JavaScript's JSON.parse() and response.json() expect valid JSON strings. When they encounter HTML (starting with <), parsing fails immediately with "Unexpected token" error. JSON parsing is strict and doesn't accept HTML syntax.
Example: JSON.parse("<html>...") throws "Unexpected token <" error
Important: Understanding HTML error pages, Content-Type headers, API redirects, and JSON parsing is key to fixing this error. The main issue is that APIs return HTML when they should return JSON, causing parsing to fail.
When: When This Error Occurs
This error occurs in these situations:
Wrong API Endpoint URL
When the API endpoint URL is incorrect (typo, wrong path, missing parameters), servers return 404 HTML error pages instead of JSON. Your code tries to parse the HTML 404 page as JSON, causing the error. Always verify API endpoint URLs are correct.
API Server Errors
When API servers encounter errors (500 Internal Server Error, database errors, crashes), they often return HTML error pages instead of JSON error responses. Your code receives HTML error pages and tries to parse them as JSON, causing the error.
CORS Errors
When CORS (Cross-Origin Resource Sharing) blocks API requests, browsers sometimes return HTML error pages or CORS error responses. These HTML responses are parsed as JSON, causing the error. CORS errors often return HTML instead of JSON error responses.
Authentication Failures
When API authentication fails (401 Unauthorized, 403 Forbidden), servers often redirect to HTML login pages or return HTML error pages. Your code receives HTML instead of JSON, causing parsing errors. Authentication failures commonly return HTML responses.
Common Scenario: This error is most common when API endpoints are wrong, servers return error pages, CORS blocks requests, or authentication fails. The main issue is receiving HTML when expecting JSON, causing JSON parsing to fail.
How To: Fix the Error
Follow these methods to fix "Unexpected token < in JSON at position 0" errors:
Method 1: Check Content-Type Before Parsing
Verify the response is JSON before parsing:
Safe JSON Parsing with Content-Type Check
async function fetchApiData(url) {
try {
const response = await fetch(url);
// Check if response is OK
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
// Check Content-Type header
const contentType = response.headers.get('content-type');
if (!contentType || !contentType.includes('application/json')) {
const text = await response.text();
throw new Error(`API returned HTML instead of JSON. Response: ${text.substring(0, 100)}`);
}
// Parse JSON safely
const data = await response.json();
return data;
} catch (error) {
if (error instanceof SyntaxError) {
console.error('JSON parse error - API returned HTML:', error);
throw new Error('API returned HTML instead of JSON. Check endpoint URL and server configuration.');
}
throw error;
}
}Method 2: Inspect Response Text First
Check response content before parsing:
Inspect Response Before Parsing
async function safeFetchJson(url) {
const response = await fetch(url);
const text = await response.text();
// Check if response is HTML
if (text.trim().startsWith('<')) {
console.error('API returned HTML:', text.substring(0, 200));
throw new Error('API returned HTML instead of JSON. Check endpoint URL.');
}
// Parse JSON
try {
return JSON.parse(text);
} catch (error) {
console.error('JSON parse error:', error);
console.error('Response text:', text.substring(0, 200));
throw new Error('Failed to parse JSON. Response may be HTML or invalid JSON.');
}
}Method 3: Handle API Errors Properly
Check response status and handle errors:
Proper Error Handling
async function fetchWithErrorHandling(url) {
const response = await fetch(url);
// Check response status
if (!response.ok) {
// Try to get error message from response
const contentType = response.headers.get('content-type');
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
if (contentType && contentType.includes('application/json')) {
try {
const errorData = await response.json();
errorMessage = errorData.message || errorData.error || errorMessage;
} catch (e) {
// Response is not JSON, might be HTML
const text = await response.text();
errorMessage = `Server returned HTML error page: ${text.substring(0, 100)}`;
}
}
throw new Error(errorMessage);
}
// Verify Content-Type
const contentType = response.headers.get('content-type');
if (!contentType || !contentType.includes('application/json')) {
throw new Error('API did not return JSON. Content-Type: ' + contentType);
}
return await response.json();
}Method 4: Fix API Server Configuration
Ensure API returns JSON, not HTML:
Express.js - Return JSON Errors
const express = require('express');
const app = express();
// Middleware to ensure JSON responses
app.use((req, res, next) => {
res.setHeader('Content-Type', 'application/json');
next();
});
// Error handler - return JSON, not HTML
app.use((err, req, res, next) => {
res.status(err.status || 500).json({
error: err.message || 'Internal Server Error',
status: err.status || 500
});
});
// 404 handler - return JSON, not HTML
app.use((req, res) => {
res.status(404).json({
error: 'Not Found',
status: 404,
path: req.path
});
});Flask - Return JSON Errors
from flask import Flask, jsonify
from werkzeug.exceptions import HTTPException
app = Flask(__name__)
# Error handler - return JSON
@app.errorhandler(HTTPException)
def handle_exception(e):
return jsonify({
'error': e.description,
'status': e.code
}), e.code
# 404 handler - return JSON
@app.errorhandler(404)
def not_found(error):
return jsonify({
'error': 'Not Found',
'status': 404
}), 404Best Practice: Always check Content-Type headers before parsing JSON, verify response status, inspect response text when errors occur, and configure APIs to return JSON error responses instead of HTML. Use try-catch blocks and provide user-friendly error messages.
Why: Why This Error Happens
"Unexpected token < in JSON at position 0" happens for these reasons:
Default Server Behavior
Web servers default to returning HTML error pages (404.html, 500.html) when errors occur. APIs should return JSON, but misconfigured servers return HTML by default. This causes JSON parsing to fail when code expects JSON but receives HTML.
Missing Error Handling
Code often assumes APIs always return JSON without checking Content-Type headers or response status. When APIs return HTML error pages, code tries to parse HTML as JSON, causing errors. Proper error handling and Content-Type checks prevent this.
API Misconfiguration
APIs may be misconfigured to return HTML instead of JSON, have wrong Content-Type headers, or redirect to HTML pages. API endpoints might not exist, causing 404 HTML pages. Server configuration issues cause APIs to return HTML when they should return JSON.
JSON Parsing Strictness
JavaScript's JSON.parse() is strict and fails immediately when encountering invalid JSON. HTML starts with "<" which is not valid JSON syntax, causing immediate parsing failure. JSON parsers don't accept HTML, requiring proper content validation before parsing.
Important: "Unexpected token < in JSON at position 0" happens because APIs return HTML instead of JSON, servers default to HTML error pages, code doesn't check Content-Type, and JSON parsing is strict. The solution is to verify Content-Type, check response status, and handle errors properly.
Frequently Asked Questions
What causes "Unexpected token < in JSON at position 0" error?
This error occurs when you try to parse HTML as JSON. The "<" character is the first character of HTML tags (<html>, <body>). Common causes include: API returning HTML error pages instead of JSON, wrong Content-Type header (text/html instead of application/json), API redirects to HTML pages, CORS errors returning HTML, and API endpoints returning HTML by default.
How do I fix API returning HTML instead of JSON?
Check the API endpoint URL is correct, verify Content-Type header is application/json, check for API errors (4xx/5xx status codes), handle redirects properly, ensure CORS is configured correctly, and check response status before parsing. Use response.headers.get("content-type") to verify the response type before calling response.json().
Why does my API return HTML error page?
APIs return HTML error pages when: the endpoint doesn't exist (404), authentication fails (401/403), server errors occur (500), the API is down, CORS blocks the request, or the server is misconfigured. HTML error pages are default server responses, while JSON APIs should return JSON error responses.
How do I check if API response is JSON or HTML?
Check the Content-Type header: response.headers.get("content-type") should be "application/json". Check response status: response.ok should be true. Inspect response text: const text = await response.text(); if (text.startsWith("<")) it's HTML. Use try-catch around JSON.parse() to handle parsing errors gracefully.
How do I handle API errors that return HTML?
Check response status before parsing: if (!response.ok) throw error. Check Content-Type: if (!response.headers.get("content-type")?.includes("json")) handle as HTML. Use response.text() first to inspect, then parse conditionally. Implement proper error handling with try-catch blocks and user-friendly error messages.