JSON.parse: unexpected character in Firefox
This is Firefox saying that the first character it could not accept sits at the line and column it names. At line 1, column 1, the text was not JSON from its very first character, which usually means a web page, a plain error message or an empty-looking file with something invisible at the front. Unlike Chrome, Firefox does not print the character, so you have to go and look at it.
Input
<html>
<head><title>504 Gateway Time-out</title></head>
</html>Do
- Paste the input into the validator.
- Press Repair in the editor band.
Result
Nothing here could be repaired automatically.| Runtime | Message |
|---|---|
| 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) |
| This site | Unexpected "<"line 1, column 1 |
␊ stands for a line break. Recorded from each runtime; the wording is in Firefox’s, Safari’s and Python’s sources.
Reading Firefox's messages
Every JSON error from Firefox follows one template: JSON.parse:, a short reason, then at line L column C of the JSON data. Lines and columns both count from one. The prefix appears even when your code never called JSON.parse itself: fetch(…).json() produces the same text, and an empty body there reads JSON.parse: unexpected end of data at line 1 column 1 of the JSON data.
The reason is the part to search for, and it maps closely onto the words Chrome uses. This table was built from what Firefox 156 printed for the example on each of the other pages here:
| Firefox's reason | Read this page |
|---|---|
unexpected character | Unexpected token < in JSON at position 0 · Expecting value: line 1 column 1 (char 0) · Unexpected token in JSON from a byte-order mark |
unexpected end of data | Unexpected end of JSON input |
expected property name or '}' | Expected property name or '}' in JSON |
expected ',' or '}' after property value in object | Expected ',' or '}' after property value in JSON |
bad control character in string literal | Bad control character in string literal |
unterminated string | Unterminated string in JSON |
expected double-quoted property name | Expected double-quoted property name in JSON |
Firefox has a few more reasons than Chrome, because it separates running out of text from meeting the wrong character. End of data when ',' or ']' was expected, for instance, is a list cut off after an item. The complete set is in SpiderMonkey's JSON parser, and each one names the thing the parser was waiting for.
Unexpected character at line 1 column 1
This variant has the same causes as the message Chrome reports as Unexpected token <. The server sent an HTML page instead of JSON: a 404 for a mistyped address, a login form after an expired session, or a proxy's 502 or 504 page like the example above. Open the Network panel in Firefox's developer tools, select the request and read its Response tab, or print the first two hundred characters of the body before parsing it. The page's title normally says what went wrong.
If the text really does look like JSON, the character at column 1 is probably one you cannot see: a byte-order mark saved at the start of a file. Firefox reports it with exactly the same words, so the only way to tell is to check the first character's code.
A column further along the line points at a character inside the document, and then the reason is worth reading closely. A single quote at column 2, for example, reports an expected property name, which is a Python dictionary rather than a server problem.
Going to the line and column
Firefox counts lines by line breaks, so a minified document is a single line and the column can run into the thousands. Any editor with a go-to-line command gets you to the right line; the column then has to be counted, which is where a tool helps. In the validator the status bar shows the cursor's position as Ln and Col, both counted from one like Firefox's, so you can click into the document and move until the numbers match. Formatting the document first does not help here: it moves every character, and Firefox's numbers describe the original text.
Checking it here
Paste the text into the JSON Validator: Code view underlines the character Firefox was pointing at and shows it, which Firefox's message does not. For an HTML page, Repair declines, as the result above shows, because extracting something JSON-shaped from a web page would give you the wrong data rather than the right error. For text that is nearly JSON, the guide to fixing invalid JSON shows what it can repair.