Fix "Unexpected End of JSON Input" Error in JavaScript
The SyntaxError: Unexpected end of JSON input error means your code tried to parse a string that looks like JSON but is incomplete. Here are the 6 most common causes and how to fix each one.
- 1. Check if the string is empty before parsing:
if (!str) return null; - 2. Always check
response.okbefore callingresponse.json() - 3. Wrap JSON.parse in try/catch — never let it crash your app
What the Error Means
JSON.parse() reads a string from start to end, expecting a complete JSON value. When it reaches the end of the string before finding a matching closing bracket, brace, or quote, it throws SyntaxError: Unexpected end of JSON input.
// These all cause the error:
JSON.parse(''); // empty string
JSON.parse('{"name"'); // missing closing brace
JSON.parse('[1, 2, 3'); // missing closing bracket
JSON.parse('"hello'); // unclosed string6 Common Causes and Fixes
Cause 1: Empty String
The most common cause — passing an empty string to JSON.parse()
// Common in fetch when server returns empty body
const response = await fetch('/api/data');
const data = await response.json(); // ← throws if body is empty
// Also with localStorage
const raw = localStorage.getItem('key'); // returns "" or null
JSON.parse(raw); // ← throws if raw is ""// Fix: check before parsing
const raw = localStorage.getItem('key');
const data = raw ? JSON.parse(raw) : null;
// Fix with fetch: check response.ok and content-length
const response = await fetch('/api/data');
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const text = await response.text();
const data = text ? JSON.parse(text) : null;Cause 2: Truncated API Response
The server sent an incomplete JSON body due to a crash, timeout, or proxy issue
// Server crashed mid-response, sending only:
// {"users": [{"id": 1, "name": "Al
// Your code:
const data = await response.json();
// ← SyntaxError: Unexpected end of JSON input// Fix: read as text first, validate, then parse
const response = await fetch('/api/data');
const text = await response.text();
try {
const data = JSON.parse(text);
} catch (e) {
console.error('Invalid JSON response:', text.slice(0, 200));
throw new Error('Server returned invalid JSON');
}Debug tip: Log the raw response text to see where it was cut off. This often reveals a server-side error (PHP memory limit, Nginx buffer overflow, etc.).
Cause 3: Missing Closing Bracket or Brace
A manually constructed JSON string with a missing closing brace or bracket
INVALID
{
"name": "Alice",
"items": [1, 2, 3
}VALID
{
"name": "Alice",
"items": [1, 2, 3]
}Fix: Use JSON.stringify() to build JSON strings instead of manual concatenation. It always produces valid JSON.
Cause 4: Unclosed String Literal
A string value that is missing its closing double quote
INVALID
{"message": "Hello world}VALID
{"message": "Hello world"}Common scenario: A string contains an unescaped double quote or newline character that terminates the string early. Use JSON.stringify() to properly escape values.
Cause 5: Network Interruption
Connection dropped mid-transfer, leaving an incomplete JSON body
// Fix: use AbortController with timeout
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 10000);
try {
const response = await fetch('/api/data', {
signal: controller.signal,
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
} catch (e) {
if (e.name === 'AbortError') {
console.error('Request timed out');
} else if (e instanceof SyntaxError) {
console.error('Invalid JSON — possible network truncation');
}
} finally {
clearTimeout(timeout);
}Cause 6: HTML Instead of JSON
Server returned an HTML error page, but your code assumes JSON
// Server returned a 404 HTML page: // <!DOCTYPE html><html>... // Your code blindly parses it: const data = await response.json(); // ← The "<!DOCTYPE" starts like a string but never closes // → "Unexpected end of JSON input"
// Fix: check Content-Type header
const response = await fetch('/api/data');
const contentType = response.headers.get('content-type');
if (!response.ok || !contentType?.includes('application/json')) {
const text = await response.text();
throw new Error(`Expected JSON, got: ${text.slice(0, 100)}`);
}
const data = await response.json();Safe JSON.parse Utility Function
Use this utility in your projects to never crash on bad JSON again:
/**
* Safely parse JSON without throwing.
* Returns fallback (null by default) on any error.
*/
function safeJsonParse<T = unknown>(
str: string | null | undefined,
fallback: T | null = null,
): T | null {
if (!str || typeof str !== 'string') return fallback;
try {
return JSON.parse(str) as T;
} catch {
return fallback;
}
}
// Usage examples:
const data = safeJsonParse(localStorage.getItem('user'));
// data is null if missing or invalid — no crash
const config = safeJsonParse<Config>(raw, defaultConfig);
// config falls back to defaultConfig if parse failsPrevention Best Practices
Frequently Asked Questions
What does "Unexpected end of JSON input" mean?
It means JSON.parse() reached the end of the string before finding a complete JSON value. The string started like valid JSON (e.g., an opening brace or bracket) but was cut off mid-structure. Common causes: empty string, truncated API response, missing closing bracket, or unclosed string literal.
How do I fix "Unexpected end of JSON input" in fetch?
Always check response.ok and the Content-Type header before calling response.json(). If the server returns an empty body or HTML error page, response.json() will throw this error. Pattern: if (!response.ok) throw new Error(`HTTP ${response.status}`); const data = await response.json();
Why does JSON.parse("") throw "Unexpected end of JSON input"?
An empty string is not valid JSON. JSON.parse() expects at least one complete value (object, array, string, number, boolean, or null). An empty string gives the parser nothing to work with, so it reports "unexpected end". To handle this, check if the string is empty before parsing: const data = str ? JSON.parse(str) : null;
Is "Unexpected end of JSON input" the same as "Unexpected token"?
No. "Unexpected end of JSON input" means the string ended too early — the parser was expecting more content. "Unexpected token" means the parser found a character it did not expect at that position (e.g., a trailing comma, a single quote, or an HTML "<" character). Both are SyntaxError types from JSON.parse().
Key Takeaways
- "Unexpected end of JSON input" means the JSON string was incomplete — it started but never finished.
- Empty strings and truncated API responses are the two most common causes.
- Always check
response.okbefore callingresponse.json(). - Use a
safeJsonParse()utility with try/catch and a fallback value. - Use our JSON Repair tool to auto-fix broken JSON, or JSON Validator to find the exact error location.