JSON error messages, explained
A JSON error message is written for the parser's convenience, not yours. Unexpected token, expected property name, Expecting value: each one describes what the parser was waiting for at the moment it gave up, and says nothing about how the text got that way. The pages below start from the message you were shown and work back to the cause.
Each page gives the smallest input that produces its message, and what Chrome and Node.js, Node.js 18, Firefox, Safari and Python print for that same input. Every one of those messages was recorded by running the input through that runtime, not written from memory. Each page also shows what this site's parser reports, and what Repair does with the input, including when it declines and why.
The messages
- Unexpected token < in JSON at position 0The response was an HTML page — a 404, a login screen or a proxy error — read as JSON.
- Unexpected end of JSON inputThe text stopped before the JSON did: an empty body, or a document cut off part-way.
- Expected property name or '}' in JSONA key in single quotes or none at all — usually a Python dict or a JavaScript object.
- Expected ',' or '}' after property value in JSONSomething other than a comma follows a value: a forgotten comma, a comment, a second value.
- Bad control character in string literalA tab or line break typed straight into a string instead of written as \t or \n.
- Unterminated string in JSONA string that never closes, most often because the text was cut off inside it.
- Expected double-quoted property name in JSONAlmost always a trailing comma before the closing brace.
- JSON.parse: unexpected character in FirefoxFirefox's wording, which names a line and a column but not the character.
- Expecting value: line 1 column 1 (char 0)Python's json module found nothing it could read at the very first character.
- Unexpected token in JSON from a byte-order markAn invisible character at the start of a file saved by a Windows editor.
Find your message
The wording changes from one runtime to the next, and even between versions of the same one. If your message is not one of the headings above, search this page for a few words from it. The list gives every message recorded for each page's example, grouped by the page that explains it.
Unexpected token < in JSON at position 0
- Chrome 153 · Node.js 26
Unexpected token '<', "<!DOCTYPE "... is not valid JSON - Node.js 18 (older V8)
Unexpected token < in JSON at position 0 - Firefox 156
JSON.parse: unexpected character at line 1 column 1 of the JSON data - Safari 26
JSON Parse error: Unrecognized token '<' - Python 3.14 json
Expecting value: line 1 column 1 (char 0)
Unexpected end of JSON input
- Chrome 153 · Node.js 26
Unexpected end of JSON input - Firefox 156
JSON.parse: unexpected end of data at line 1 column 18 of the JSON data - Safari 26
JSON Parse error: Unexpected EOF - Python 3.14 json
Expecting value: line 1 column 18 (char 17)
Expected property name or '}' in JSON
- Chrome 153 · Node.js 26
Expected property name or '}' in JSON at position 1 (line 1 column 2) - Node.js 18 (older V8)
Unexpected token ' in JSON at position 1 - Firefox 156
JSON.parse: expected property name or '}' at line 1 column 2 of the JSON data - Safari 26
JSON Parse error: Single quotes (') are not allowed in JSON - Python 3.14 json
Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
Expected ',' or '}' after property value in JSON
- Chrome 153 · Node.js 26
Expected ',' or '}' after property value in JSON at position 10 (line 2 column 2) - Node.js 18 (older V8)
Unexpected string in JSON at position 10 - Firefox 156
JSON.parse: expected ',' or '}' after property value in object at line 2 column 2 of the JSON data - Safari 26
JSON Parse error: Expected '}' - Python 3.14 json
Expecting ',' delimiter: line 2 column 2 (char 10)
Bad control character in string literal
- Chrome 153 · Node.js 26
Bad control character in string literal in JSON at position 13 (line 1 column 14) - Node.js 18 (older V8)
Unexpected token ␉ in JSON at position 13 - Firefox 156
JSON.parse: bad control character in string literal at line 1 column 14 of the JSON data - Safari 26
JSON Parse error: Unterminated string - Python 3.14 json
Invalid control character at: line 1 column 14 (char 13) - Chrome 153 · Node.js 26
Bad control character in string literal in JSON at position 20 (line 1 column 21) - Node.js 18 (older V8)
Unexpected token ␊ in JSON at position 20 - Firefox 156
JSON.parse: bad control character in string literal at line 1 column 21 of the JSON data - Python 3.14 json
Invalid control character at: line 1 column 21 (char 20)
Unterminated string in JSON
- Chrome 153 · Node.js 26
Unterminated string in JSON at position 21 (line 1 column 22) - Node.js 18 (older V8)
Unexpected end of JSON input - Firefox 156
JSON.parse: unterminated string at line 1 column 22 of the JSON data - Safari 26
JSON Parse error: Unterminated string - Python 3.14 json
Unterminated string starting at: line 1 column 19 (char 18)
Expected double-quoted property name in JSON
- Chrome 153 · Node.js 26
Expected double-quoted property name in JSON at position 24 (line 1 column 25) - Node.js 18 (older V8)
Unexpected token } in JSON at position 24 - Firefox 156
JSON.parse: expected double-quoted property name at line 1 column 25 of the JSON data - Safari 26
JSON Parse error: Property name must be a string literal - Python 3.14 json
Illegal trailing comma before end of object: line 1 column 24 (char 23)
JSON.parse: unexpected character in Firefox
- Chrome 153 · Node.js 26
Unexpected token '<', "<html>␊<he"... is not valid JSON - Node.js 18 (older V8)
Unexpected token < in JSON at position 0 - Firefox 156
JSON.parse: unexpected character at line 1 column 1 of the JSON data - Safari 26
JSON Parse error: Unrecognized token '<' - Python 3.14 json
Expecting value: line 1 column 1 (char 0)
Expecting value: line 1 column 1 (char 0)
- Chrome 153 · Node.js 26
Unexpected token 'I', "Internal S"... is not valid JSON - Node.js 18 (older V8)
Unexpected token I in JSON at position 0 - Firefox 156
JSON.parse: unexpected character at line 1 column 1 of the JSON data - Safari 26
JSON Parse error: Unexpected identifier "Internal" - Python 3.14 json
Expecting value: line 1 column 1 (char 0)
Unexpected token in JSON from a byte-order mark
- Chrome 153 · Node.js 26
Unexpected token '[U+FEFF]', "[U+FEFF]{"id": 7}" is not valid JSON - Node.js 18 (older V8)
Unexpected token [U+FEFF] in JSON at position 0 - Firefox 156
JSON.parse: unexpected character at line 1 column 1 of the JSON data - Safari 26
JSON Parse error: Unrecognized token '[U+FEFF]' - Python 3.14 json
Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column 1 (char 0)
Positions differ between runtimes as well. Chrome's position and Python's char count characters from zero; every line and column counts from one. A symbol in square brackets, or ␉ and ␊, marks a character the runtime printed invisibly: a byte-order mark, a tab or a line break.
Before you read any of them
Every page follows the same order. The message comes first, then the smallest input that causes it, then a table of what each runtime prints for that input. After that comes the usual cause in real programs, how to confirm it, and whether the fix belongs in your code or in the text. The example on each page opens in the validator with one click, already pasted, so you can watch the error and the repair happen.
Most JSON errors in a running program are not about JSON. The server sent a web page, an empty body or half a response, and the parser was simply the first thing to notice. So when a message points at line 1, column 1, look at the raw text before the code: print its first two hundred characters, or open the request in the browser's Network panel.
When the text is yours and nearly right, paste it into the JSON Validator to see where it fails, and use JSON Repair for the familiar ones: single quotes, comments, trailing commas, Python literals and cut-off endings. The guide to fixing invalid JSON walks through a file with five different mistakes. Nothing you paste leaves your browser.