How to fix Unexpected token errors in JSON
Tools Nimbus is a free, no-signup developer toolkit that runs entirely in your browser, so your data is never uploaded to a server. The fastest way to fix an Unexpected token error is to paste the text into the Tools Nimbus JSON Formatter, read the line and column it reports, and check the character just before that position for one of the seven causes below.
Last updated June 2026
What the error actually tells you
JSON parsers read your text one token at a time: braces, brackets, commas, colons, strings, numbers, and the literals true, false, and null. The moment the parser meets a character that the grammar does not allow at that position, it stops and names that character in the error. That is all the message means. The named token is where the parser gave up, not necessarily where you made the mistake, and the real problem is usually the character or line immediately before it.
Browsers phrase the message differently, which confuses searches. Chrome and Node say Unexpected token x in JSON at position 123, Firefox says JSON.parse: unexpected character at line 4 column 2, and Safari says Unexpected identifier. They are all the same class of failure and the same fixes apply.
The seven causes, from most to least common
| Error mentions | Most likely cause | Fix |
|---|---|---|
token < at position 0 | The text is HTML, not JSON (404 page, redirect, error page) | Log the raw response, check the URL and status code |
token ' | Single quotes around keys or strings | Replace with double quotes |
token } or token ] | Trailing comma after the last item | Delete the final comma |
token a, token N, other letters | Unquoted key, or a JavaScript value like undefined or NaN | Quote the key; use null instead of undefined or NaN |
token " mid-document | Missing comma between properties, or an unescaped quote inside a string | Add the comma, or escape the inner quote as \" |
| Unexpected end of JSON input | Truncated text: an unclosed brace, bracket, or string | Check the response was fully received and every opener is closed |
token / | Comments in the file | Remove them; JSON does not allow comments |
Step 1: confirm the text is JSON at all
If the error names < at position 0, stop debugging the JSON, because there is no JSON. Your code received an HTML document. This happens when an API route returns a 404 page, when an expired session redirects to a login page, when a proxy serves an error page, or when a single-page app serves index.html for an API path it does not recognize. Print the first 200 characters of the raw response and the HTTP status code. Fix the request, not the parser.
Step 2: locate the exact failing position
For everything else, you need the line and column. Reading a position number like 4132 out of a minified one-line blob is hopeless by eye, so let a validator do it. Paste the text into the JSON Formatter: it parses in your browser, names the first illegal character, and shows where it sits. Because parsing stops at the first error, a file can contain several mistakes; fix the first, re-validate, and repeat until it formats cleanly. Nothing you paste leaves your machine, which matters when the payload contains tokens, emails, or customer data.
Step 3: fix the JavaScript habits
Most remaining failures are JavaScript syntax written into a JSON document. JSON looks like a JavaScript object literal but is a much stricter grammar, and the differences are exactly the habits that break it: single quotes, unquoted keys, trailing commas, comments, and values like undefined or NaN that JSON simply does not have. If you are producing JSON from code, never concatenate strings by hand. Build the object and call JSON.stringify, which cannot emit any of these mistakes. If a string value contains a double quote, it must be escaped as \", and literal newlines inside strings must be \n.
Step 4: check for truncation and invisible characters
Unexpected end of JSON input means the parser ran out of text with structures still open: a brace, bracket, or string that never closes. Logs that cap line length, copy-paste that missed the final lines, and network responses cut off mid-transfer all produce it. Two subtler culprits are worth knowing. A UTF-8 byte order mark at the very start of a file is invisible in most editors but illegal in JSON, and so are smart quotes pasted from a chat app or word processor, which look like straight quotes and are not. Re-typing the quotes and saving the file without a BOM fixes both.
Preventing the error
- Generate JSON with
JSON.stringifyor your language's serializer, never by hand or string concatenation. - Validate before you ship: paste config files and API fixtures into the JSON Formatter after editing them.
- In fetch code, check
response.okand theContent-Typeheader before callingresponse.json(), so HTML error pages fail loudly with a useful message instead of a parse error. - If your payload travels inside a URL or a JWT, encode it with the URL Encoder or inspect it with the JWT Decoder rather than hand-editing the encoded form.