JSON parse errors: what each message means
Look up the error message you’re seeing to find out what causes it and how to fix it. The JavaScript messages below are the ones Chrome, Edge, and Node.js 20 and later show. Firefox, Safari, and Python word them differently, and the Python versions are listed too.
Most JSON errors come down to one of two problems. Either the text you tried to parse isn’t JSON at all, which usually means an API request went wrong, or it’s JSON with a syntax mistake in it. If the error points to the very first character (position 0, or line 1 column 1), start with the first group.
If your JSON parses but an API still rejects it, the problem is usually the data rather than the syntax: a missing field, a number sent as a string, or a value that isn’t allowed. The JSON Schema validator finds those when you have the API’s schema.
Each entry includes a broken example you can open in the JSON validator. It underlines the error, and Fix My JSON repairs it. Your own JSON works the same way: paste it in, and it stays in your browser.
Finding where the error is
Most error messages tell you where the parser gave up. Take this example, where the comma after "Maya" is the mistake:
{"name": "Maya",}
^| Where | Message |
|---|---|
| Chrome, Edge, Node.js | Expected double-quoted property name in JSON at position 16 (line 1 column 17) |
| Python | Expecting property name enclosed in double quotes: line 1 column 17 (char 16) |
| Firefox | JSON.parse: expected double-quoted property name at line 1 column 17 of the JSON data |
All three point to the same character, the } marked above. Line and column numbers start at 1, so column 17 is the 17th character. Chrome’s “position” and Python’s “char” count from 0 instead, which is why they say 16.
Notice that the parser stops at the }, one character after the comma that caused the problem. It only knows something is wrong once it reaches a character that can’t come next, so look at the reported spot and just before it.
In a long document, print the text around that spot. In JavaScript:
try {
JSON.parse(text);
} catch (error) {
const position = Number(error.message.match(/position (\d+)/)?.[1]);
if (!Number.isNaN(position)) {
console.log(text.slice(Math.max(0, position - 30), position + 30));
}
}In Python, JSONDecodeError has the position built in:
import json
try:
data = json.loads(text)
except json.JSONDecodeError as error:
print(f"Line {error.lineno}, column {error.colno}")
print(text[max(0, error.pos - 30):error.pos + 30])Or paste the JSON into the JSON validator. It highlights the line with the first error and links to the guide for that kind of mistake.
The input isn’t JSON
When the text isn’t JSON, the error almost always points to the first character. The fix is in the request or code that produced the text, not in the text itself.
The text is an HTML page
- JavaScript
Unexpected token '<', "<!DOCTYPE "... is not valid JSONUnexpected token < in JSON at position 0- Python
Expecting value: line 1 column 1 (char 0)
The server sent a web page instead of JSON. It’s usually a 404 page, a login page, or an error page from a proxy.
Example
<!DOCTYPE html>
<html>
<head><title>404 Not Found</title></head>
</html>Fix My JSON can’t turn a web page into JSON. The fix is in the request that returned it. Open it in the validator
The text is empty or cut off
- JavaScript
Unexpected end of JSON inputJSON Parse error: Unexpected EOF- Python
Expecting value: line 1 column 1 (char 0)
The response had no body, such as a 204 No Content response, or the JSON stops before its closing brackets.
Example
{
"id": 42,
"roles": ["editor", "admin"Fix My JSON closes the open brackets, but it can’t bring back what was cut off. Open it in the validator
The value isn’t JSON text
- JavaScript
"undefined" is not valid JSON"[object Object]" is not valid JSON
JSON.parse was given undefined, or an object that has already been parsed. response.json() and axios’s response.data both return parsed objects, so there’s nothing left to parse.
An invisible character at the start
- JavaScript
Unexpected token '', "{"a":1}" is not valid JSON- Python
Unexpected UTF-8 BOM (decode using utf-8-sig)
The file begins with an invisible byte order mark (BOM), which the JSON standard doesn’t allow. Save the file as UTF-8 without BOM, or in Python open it with encoding="utf-8-sig".
The JSON has a syntax error
These errors point somewhere in the middle of the text. They’re most common in JSON that was written by hand or put together by joining strings, which is a good reason to generate JSON with JSON.stringify or json.dumps instead.
A property name isn’t in double quotes
- JavaScript
Expected property name or '}' in JSON at position 1Expected double-quoted property name in JSON at position 16- Python
Expecting property name enclosed in double quotes
A property name uses single quotes or no quotes, there’s a comma right before }, or there’s a comment. This usually means the text is a Python dictionary or a JavaScript object rather than JSON.
Example
{'name': 'Maya', age: 30}Fix My JSON adds the missing double quotes. Open it in the validator
A trailing comma
- JavaScript
Expected double-quoted property name in JSON at position 16Unexpected token ']', "[1,]" is not valid JSON- Python
Expecting property name enclosed in double quotesExpecting value
There’s a comma after the last item in an object or array. JavaScript allows that in code, but JSON doesn’t.
A value is missing or invalid
- JavaScript
Unexpected token 'N', "{"a": NaN}" is not valid JSON- Python
Expecting value: line 1 column 7 (char 6)
A value is missing, as in "a": ,, is in single quotes, or is something JSON doesn’t support, such as NaN, undefined, or Python’s None.
Example
{"id": 7, "owner": , "score": NaN}Fix My JSON fills in the missing value with null. It turns NaN into the text “NaN”, so replace that with a real number or null. Open it in the validator
A missing comma or colon
- JavaScript
Expected ',' or '}' after property value in JSON at position 8Expected ',' or ']' after array element in JSON at position 3Expected ':' after property name in JSON at position 5- Python
Expecting ',' delimiterExpecting ':' delimiter
Two items aren’t separated by a comma, or a property name isn’t followed by a colon. An unescaped " inside a string causes the same error, because the parser thinks the string ends there. If the position in the message equals the length of your text, the JSON was cut off.
Extra text after the JSON
- JavaScript
Unexpected non-whitespace character after JSON at position 7- Python
Extra data: line 2 column 1 (char 8)
There’s more text after the JSON value ends, often a second JSON object. A file with one JSON value on each line is JSON Lines (also called NDJSON), and each line has to be parsed separately.
Example
{"id": 1}
{"id": 2}Fix My JSON wraps the two objects in an array. If the file is JSON Lines, parse each line on its own instead. Open it in the validator
A line break or tab inside a string
- JavaScript
Bad control character in string literal in JSON at position 10- Python
Invalid control character at: line 1 column 11 (char 10)
A string contains an actual line break or tab character. Inside JSON strings, these have to be written as \n and \t. JSON.stringify and json.dumps escape them automatically, and so does the JSON escape tool.
Example
{"note": "line one
line two"}Fix My JSON escapes the line break as \n. Open it in the validator
A string is never closed
- JavaScript
Unterminated string in JSON at position 12- Python
Unterminated string starting at: line 1 column 7 (char 6)
A string is missing its closing quote. Either the text was cut off, or a quote inside the string wasn’t escaped as \".
Example
{"name": "Maya}Fix My JSON closes the string. Check the result, because it can’t know where the string was meant to end. Open it in the validator
Python can write invalid JSON
By default, Python’s json.dumps writes NaN and infinity as they are, so json.dumps({"x": float("nan")}) produces {"x": NaN}. Python can read that back, but JSON.parse and most other parsers reject it. Convert these values to None before encoding, or pass allow_nan=False so that json.dumps raises an error instead of writing invalid JSON. JavaScript’s JSON.stringify writes null for these values.