JSON guide · 5 min read
Unexpected Token in JSON: What It Means and How to Fix It
Decode unexpected-token JSON errors, inspect the raw response and fix the syntax or HTTP problem that actually caused parsing to fail.
What an unexpected token error actually tells you
A JSON parser reads the document from left to right according to a strict grammar. An unexpected token error means the parser reached a character that cannot legally appear at that point. The token is where parsing stopped, but the true mistake can be earlier, such as a missing quote or comma.
Browser and runtime messages vary. Some report a character position, some a line and column, and newer engines may describe the expected syntax rather than literally saying 'unexpected token'. The debugging method is the same: preserve the raw input, identify the failing location and inspect the context around it.
Unexpected token < usually means HTML, not JSON
If the first unexpected character is <, the response often begins with <!doctype html> or an HTML tag. Common causes include a 404 page, authentication redirect, reverse-proxy error, framework fallback route or CDN error page.
Do not immediately modify JSON.parse. First verify that the requested URL and response are correct. An API client should normally check the status code and Content-Type before treating the body as JSON.
const response = await fetch("/api/orders");
const contentType = response.headers.get("content-type") ?? "";
const body = await response.text();
if (!response.ok) {
throw new Error("HTTP " + response.status + ": " + body.slice(0, 120));
}
if (!contentType.includes("application/json")) {
throw new Error("Expected JSON, received " + contentType);
}
const data = JSON.parse(body);Position 0: inspect empty responses, prefixes and wrong endpoints
A failure at position 0 means parsing could not even begin. The body may be empty, contain plain text such as Unauthorized, begin with HTML or include an unexpected encoding marker. Printing only the parsed object hides this evidence, so inspect the raw body while debugging.
A 204 No Content response is a valid HTTP response with no body, but JSON.parse on an empty string still fails. Handle no-content statuses separately rather than forcing every successful request through the same parsing path.
Unexpected } or ] often points to a trailing comma or missing value
Closing delimiters become unexpected when the parser was still waiting for another value. A trailing comma is the classic example, but an empty property value or prematurely closed nested structure can produce a similar message.
Invalid:
{"name":"Ada",}
{"name": }
Valid:
{"name":"Ada"}
{"name": null}Unexpected u often comes from parsing undefined
In JavaScript, JSON.parse expects a string. Accidentally passing undefined is effectively trying to parse the text 'undefined', which is not JSON. This often happens when a storage key is missing, an object property was misspelled or asynchronous data has not arrived yet.
Check the value and its type before parsing. If you already have a JavaScript object, you normally should not call JSON.parse on it at all.
const raw = localStorage.getItem("settings");
if (raw !== null) {
const settings = JSON.parse(raw);
}Unexpected end of JSON input means the document ended too soon
An end-of-input error commonly indicates a truncated response, missing closing brace or bracket, an unterminated string, or an empty body. Network interruption and partial file writes can produce the same symptom as a hand-edited syntax error.
If the payload came from a network or file pipeline, compare its byte length with the producer's output and verify that transport or logging systems did not truncate it before debugging individual characters.
Use the reported position without trusting it blindly
Copy the original payload into the JSON Syntax Validator and locate the reported line or position. Then inspect both sides of that point. A missing quote can cause the parser to consume later punctuation as part of a string, so the first visibly strange token may be downstream from the actual error.
For a very large document, create a minimal reproduction by extracting the smallest enclosing object or array. Keep the original payload unchanged for comparison so that the simplification itself does not introduce a new problem.
A practical API-debugging checklist
When an unexpected-token error appears after an HTTP call, debug the transport and the JSON together. This prevents hours of editing a payload that was never JSON in the first place.
- Confirm the exact request URL, method and authentication state.
- Check the HTTP status before parsing.
- Inspect Content-Type and a redacted prefix of the raw body.
- Validate the raw JSON text without reformatting it first.
- Repair syntax only after confirming the server returned the intended representation.
- Add automated tests for the failing response shape once the issue is understood.
Primary sources
References and specifications
- RFC 8259 — The JavaScript Object Notation (JSON) Data Interchange Format
The IETF specification for JSON syntax, values, interoperability and parser behavior.
- ECMA-404 — The JSON Data Interchange Syntax
The concise ECMA definition of JSON grammar.
Common questions
Frequently asked questions
Why does JSON.parse fail on an API response that worked yesterday?
The endpoint may now be returning an error page, authentication response, empty body or malformed payload. Inspect status, Content-Type and raw response text before changing the parser.
Is the token named in the error always the actual mistake?
No. The parser reports where it became impossible to continue. A missing quote, comma or delimiter earlier in the document can make a later token appear unexpected.
Why does JSON.parse(undefined) fail?
undefined is not a JSON value. In JavaScript this often means the expected string was missing. Check for null or undefined before parsing and avoid parsing values that are already objects.
What should I do with a 204 response?
Treat it as a successful response with no body. Do not call JSON.parse on an empty string; branch on the status or content length first.