The 10 Most Common JSON Validation Errors (and How to Fix Them)
Every JSON parse error in production traces back to one of ten root causes. This is the field guide — what each error means, why it happened, and the exact fix.
You paste a JSON payload into a parser. You get back: Unexpected token } in JSON at position 247. You stare at the screen. The JSON looks fine. Where the hell is position 247?
Twenty years of JSON in the wild, and the same handful of errors trip everyone up. This is the field guide. For each, you get: what the parser is actually complaining about, the most common root cause, and the fix.
If your error doesn’t appear here, paste your input into the JSON Formatter — it shows the exact line and column of any parse failure.
1. Trailing comma
{
"name": "Ada",
"role": "admin",
}
Error: Unexpected token } in JSON at position N
What’s wrong: JavaScript allows trailing commas in object and array literals. JSON does not. The comma after "admin" makes the parser expect another key/value pair, then it sees } and dies.
Fix: Delete the comma after the last item.
{
"name": "Ada",
- "role": "admin",
+ "role": "admin"
}
Why this happens: Most JSON in the wild is hand-edited at some point. Hand-editing introduces trailing commas as a courtesy to the next person who adds a field. Helpful in code, fatal in JSON.
Tooling note: JSON5 and JSONC (JSON with comments) both allow trailing commas. If you need them, use one of those formats — but understand most parsers don’t support them.
2. Single quotes
{'name': 'Ada'}
Error: Unexpected token ' in JSON at position 1
What’s wrong: JSON requires double quotes around strings and keys. Single quotes are a JavaScript convenience that didn’t make the JSON spec.
Fix: Replace every ' with ". In editors that support it, do this with a regex: find ', replace with ".
Watch out for: Strings that legitimately contain a single quote (apostrophes). After global replace, those become broken. Better tactic: use your editor’s “convert string quotes” feature, which handles escaping properly.
3. Unquoted keys
{name: "Ada"}
Error: Unexpected token n in JSON at position 1
What’s wrong: JSON requires keys to be strings, which means double-quoted. JavaScript object literals can have unquoted keys; JSON cannot.
Fix: Wrap every key in double quotes.
-{name: "Ada"}
+{"name": "Ada"}
Source of confusion: People paste JavaScript object syntax thinking it’s JSON. They look the same. They are not the same.
4. Unescaped quotes inside strings
{"quote": "She said "hello""}
Error: Unexpected token h in JSON at position 14
What’s wrong: The string ended at the second ", then the parser saw hello as a bare identifier and failed.
Fix: Escape every literal double quote inside a string with \.
-{"quote": "She said "hello""}
+{"quote": "She said \"hello\""}
Other characters that need escaping inside JSON strings: \ (backslash), " (double quote), and the control characters \n (newline), \t (tab), \r (carriage return), \b, \f. Forward slashes (/) may be escaped but don’t need to be.
5. Raw newlines inside strings
{"description": "Line one
Line two"}
Error: Bad control character in string literal in JSON at position N
What’s wrong: JSON strings cannot contain literal newlines. The newline must be escaped as \n.
Fix:
-{"description": "Line one
-Line two"}
+{"description": "Line one\nLine two"}
Where this comes up: When you paste multi-line text into a JSON field by hand. Most generators (JSON.stringify, json.dumps, etc.) handle the escape automatically.
6. JavaScript values that aren’t valid JSON
{"value": undefined}
{"x": NaN}
{"y": Infinity}
Error: Unexpected token u in JSON at position N (or N for NaN, I for Infinity)
What’s wrong: undefined, NaN, and Infinity exist in JavaScript but not in JSON. They’re not in the seven valid value types.
Fix:
- For
undefined→ omit the key entirely, or usenull - For
NaN→ usenullor a string like"NaN"if you need the distinction - For
Infinity→ use a sentinel like"Infinity"or a sentinel number like9999999999
Generator behavior: Most JSON serializers handle this for you. JSON.stringify({x: undefined}) returns {} (omits the key). JSON.stringify({x: NaN}) returns {"x":null}. Don’t fight your serializer — but if you’re hand-writing JSON, you must use valid values.
7. Single-line vs block comments
// This is a config
{"timeout": 30}
Error: Unexpected token / in JSON at position 0
What’s wrong: JSON has no comments. Period. The // This is a config line is invalid before the JSON document starts.
Fix: Strip all comments before parsing. If you need commented configs, use:
- JSONC (JSON with comments) — supported by VS Code, TypeScript configs
- JSON5 — fuller-featured, supports comments + trailing commas + unquoted keys
- YAML — has comments natively (use our YAML to JSON converter at deploy time)
Tactic if you have JSON-with-comments: Strip comments with a regex before parsing — there are libraries (strip-json-comments, jsonc-parser) that do this safely. Don’t use a naïve regex; you’ll mangle URLs containing //.
8. Multiple root values
{"a": 1}
{"b": 2}
Error: Unexpected token { in JSON at position N
What’s wrong: A JSON document has exactly one root value. The first {...} is the document; everything after is invalid.
Fix: Wrap in an array, an envelope object, or use NDJSON (newline-delimited JSON, common in log streams) where each line is a separate complete JSON document.
-{"a": 1}
-{"b": 2}
+[{"a": 1}, {"b": 2}]
Real-world context: This error explodes during log parsing — a log file with one JSON event per line is not a single JSON document. Parse line-by-line.
9. Numbers that exceed safe integer range
{"id": 9007199254740993}
Not a parse error — but a correctness error. JSON numbers are conventionally parsed as IEEE 754 64-bit floats, which lose precision above 2⁵³ (9007199254740992). The number above gets parsed as 9007199254740992, off by one.
Fix: For 64-bit IDs, use strings: {"id": "9007199254740993"}. The Twitter API famously made this fix after tweet_id mangled in JS clients.
Languages that handle this differently: Python’s json.loads returns int (arbitrary precision, fine). JavaScript’s JSON.parse returns Number (loses precision). The JSON itself is valid in both cases — the loss happens at parse time. Use BigInt-aware parsers when precision matters.
10. Encoding mismatch (UTF-8 vs other)
You see characters like é rendered as é or é rendered when you didn’t ask for unicode escapes.
What’s wrong: JSON is UTF-8 by default per RFC 8259. If you’re parsing a file or HTTP response declared with a different encoding (Windows-1252, Latin-1), the bytes get misinterpreted.
Fix: Always serialize and parse JSON as UTF-8. Set Content-Type: application/json; charset=utf-8 on HTTP responses. When reading files, open them with explicit utf-8 encoding. Never let the parser guess.
Validate your fix: Paste the parsed string into the JSON Formatter. If é displays as é, encoding is correct. If you see é or similar, it’s still mangled.
The fastest fix workflow
When you hit a JSON parse error in production:
- Find the position. The parser tells you a position number. Convert to line+column with the JSON Formatter — it shows exact location on parse failure.
- Look 1-3 characters before the position. The error message says where the parser gave up, not where the bug is. The bug is usually a few characters earlier.
- Run the input through a formatter. Even if it parse-fails, modern formatters point at the offending character with line+column. That cuts your debug time by 90%.
- If the data is generated, fix the generator. Hand-fixing the JSON output in a log doesn’t solve next week’s ticket. Find what produced the malformed JSON and fix the source.
Common-cases summary table
| Error | Root cause | Quick fix |
|---|---|---|
Unexpected token } near end | Trailing comma | Delete the trailing , |
Unexpected token ' | Single quotes for strings | Replace ' with " |
Unexpected token at key | Unquoted keys | Wrap keys in " |
Unexpected token h (or any letter) inside string | Unescaped " | Escape with \" |
Bad control character | Raw newline in string | Escape as \n |
Unexpected token u/N/I | undefined/NaN/Infinity | Replace with null |
Unexpected token / | Comments | Strip comments or use JSON5 |
Unexpected token { mid-doc | Multiple roots | Wrap in array, or parse NDJSON |
| Wrong number value | 64-bit ID precision loss | Use string for IDs |
| Mangled accented chars | Encoding mismatch | Force UTF-8 everywhere |
A working principle
JSON is unforgiving by design. That’s a feature, not a bug. A strict format means tools can rely on the structure being exactly what the spec says. Every “error” above is JSON refusing to make assumptions about what you meant.
Embrace the strictness. Use a formatter before you debug. Validate at every system boundary. And never, ever commit a JSON file with a trailing comma — even if your editor lets you.
Further reading
Related posts
- What Is JSON and Why You Should Always Format It — JSON is the universal data format of the modern web. This is what it actually is…
Related tool
Format, validate, and beautify JSON online. 100% client-side — your data never leaves your browser.
Written by Mian Ali Khalid. Part of the Data & Format pillar.