ToolForge
TroubleshootingJSON

Why Your JSON Is Invalid — Every Error Explained

A JSON parser gives you one error and stops, which makes debugging feel harder than it is. There are really only about eight ways a JSON document can be malformed, and the message you have usually narrows it to one or two.

Find your error message below. Each section says what the parser was doing when it gave up, what almost always causes it, and how to fix it.

Written by toolforge.websitePublished Last reviewed How we build and check these tools

First: read the position, not the message

Every JSON parse error carries a character offset — Unexpected token } in JSON at position 412 — and that offset is the single most useful piece of information you have. It is exact. The token named in the message is often not the mistake; it is the first place the parser could no longer make sense of the document, which is frequently just after the real problem.

That distinction explains the most confusing category of error. A missing comma is reported at the next token, not at the gap. An unterminated string is reported wherever the parser eventually gave up, which can be hundreds of characters later.

Practically: paste the document into the formatter, which converts the position into a line number and highlights it, and look at the token before the one named. Browsers differ in wording — Chrome, Edge and Node use V8's phrasing, Firefox says things like SyntaxError: JSON.parse: unexpected character at line 1 column 5, Safari has its own — but all of them tell you where.

If the whole document is one line, the line number will say 1 and only the offset is useful. Format it first, then re-parse, and the error moves to a line you can see.

Unexpected token } or ] — a trailing comma

The most common JSON error there is.

{
  "name": "Ada",
  "born": 1815,
}

That comma after 1815 is legal in JavaScript, in Python, and in most people's muscle memory. It is a hard syntax error in JSON, in both objects and arrays, and MDN's JSON.parse documentation demonstrates exactly this failure. The parser reads the comma, expects another member, finds } and reports the brace — which is why the message points at a character that looks perfectly innocent.

Fix: remove the comma. If your editor added it, that is a formatter configured for JavaScript rather than JSON. The repair function in the formatter removes trailing commas throughout a document in one pass.

The same message with ] is the array version of the identical mistake.

Unexpected token ' — single quotes

JSON has no single-quoted strings, for keys or values, anywhere.

{ 'name': 'Ada' }

Both quotes are wrong here, and so is the unquoted variant { name: "Ada" }. This error almost always means the text started life as a JavaScript or Python literal and was pasted in as if it were JSON. Python is the worst offender: str() on a dict produces single quotes, capitalised True/False and None, none of which are JSON. Python's own json.dumps produces correct JSON — the mistake is using the wrong function.

Fix: double quotes throughout. The formatter's repair converts single-quoted strings to double-quoted ones with a state machine rather than a find-and-replace, so an apostrophe inside an already-valid string — "it's fine" — survives instead of being turned into a broken quote.

Unexpected token in a key position — an unquoted key

{ name: "Ada", born: 1815 }

Valid JavaScript, invalid JSON. Every key must be a double-quoted string.

This is the signature of a payload copied out of source code, a browser console, or a log line that printed an object rather than serialising it. It is also what you get from a hand-written config file where the author reasonably assumed the quotes were optional.

Fix: quote every key. The repair handles this too, and it is careful about where it applies: quoting bare keys with a naive regex on the whole document rewrites the inside of strings as well, turning {"url": "http://example.com"} into nonsense because of the colon after http. The tool's repair only rewrites structure outside string literals for exactly that reason.

Unexpected end of JSON input — the document is truncated

The parser reached the end of the text still waiting for something: a closing brace, a closing bracket, or the rest of a string.

Three causes, in order of how often they happen:

The response was empty. Parsing an empty string produces exactly this error, and an empty string is what you get from a 204 response, a failed request whose body you never checked, or a fetch that resolved before the body arrived. This is the most common cause by a wide margin, and the fix is upstream: check the status and whether the body is non-empty before parsing.

A brace or bracket is unclosed. Count them, or let the formatter do it. Deeply nested documents assembled by hand are where this lives.

The transfer was cut off. A file copy interrupted mid-write, a stream that closed early, a log rotated between the write and the read. If the document ends mid-value, this is why.

Fix: if the text is empty, fix the caller rather than the JSON. Otherwise, close what is open — the position of the last successfully parsed token tells you which container you are still inside.

Bad control character in string — an unescaped newline

A literal line break inside a quoted string is invalid, and so is a literal tab. They must be written as the escapes \n and \t.

This is the error that catches multi-line content: a PEM certificate, a SQL query, an address block, a log message with a stack trace in it. All of them contain real newlines, and all of them have to be escaped before they can sit inside a JSON string.

Firefox words it differently — bad control character in string literal — but it is the same problem.

Fix: escape the string before embedding it. The escape tool does this mechanically, and escaping strings in JSON covers the nesting case, where a value that is itself JSON needs its quotes and backslashes escaped a second time.

The related failure is an unterminated string, which is what you get when a quote inside a string was not escaped: {"quote": "she said "hi""}. The parser closes the string at the second quote and then finds a bare word where it wanted a comma.

Unexpected token N, I or u — NaN, Infinity, or undefined

NaN, Infinity, -Infinity and undefined are not JSON values. Neither are True, False and None — JSON's literals are lowercase true, false and null.

Where these come from:

  • A serialiser that was not a JSON serialiser. Something printed a language-native representation instead of encoding it.
  • A division by zero upstream. JavaScript's JSON.stringify converts NaN and Infinity to null rather than erroring, so if you are seeing the literal text NaN, the document was not produced by JSON.stringify.
  • Python. json.dumps will happily emit NaN and Infinity by default, which is valid to Python's own parser and invalid to almost everyone else's. Pass allow_nan=False and it raises instead of producing something no one else can read.

Fix: decide what those values should mean in your data — null, a string, or an omitted key — and fix the producer. There is no way to represent them in JSON, so this one cannot be patched at the parsing end.

The document looks perfect and still fails

When the error points at position 0 or 1 and the first character is visibly fine, the problem is a character you cannot see.

A byte-order mark. A file saved as "UTF-8 with BOM" begins with three invisible bytes, and most JSON parsers reject them. This is the single most maddening JSON error, because the document is genuinely correct — copy the text into a fresh file and it parses, which makes the original look haunted. Save without a BOM, or strip the first three bytes.

Non-breaking spaces. Text copied from a web page, a PDF or a word processor can contain U+00A0 where you think there is a space. JSON permits only four whitespace characters between tokens — space, tab, carriage return, line feed — and a non-breaking space is none of them.

Smart quotes. The same sources substitute typographic quotes for straight ones. A curly quote is not a string delimiter; it is just a character, and the parser says so.

Fix: retype the first line, or paste through a plain-text editor. If you suspect an invisible character, a hex view of the first bytes settles it immediately.

There is also the case where the document parses fine and is still wrong, which no parser will help with. A payload that is well-formed but has every field misspelled is valid JSON — see how to validate JSON for what validation does and does not prove.

It was never JSON

Worth checking before spending an afternoon on the syntax. Three things arrive labelled as JSON regularly and are not:

A JavaScript object literal. Unquoted keys, single quotes, trailing commas, comments, functions. Everything above, in one document.

JSON5 or JSONC. Deliberate supersets that add comments and relaxed quoting, used for config files. Your editor accepts them because it uses a lenient parser; a strict one will not. Strip the comments or use a parser that expects the dialect.

YAML. If the file has indentation-based structure and key: value lines without braces, it is YAML, and the converter will turn it into JSON. Confusingly, valid JSON is also valid YAML — the relationship only runs one way, which is why a YAML parser accepts your JSON but not the reverse. The comparison explains the overlap.

JSON Parse Tool

Parse JSON strings into JavaScript objects. It runs in your browser, so the files never leave your machine, and there is nothing to install or sign up for.

Try the JSON Parse Tool

Frequently asked questions

What does "Unexpected token o in JSON at position 1" mean?

You passed an object to a JSON parser instead of a string. The object was converted to the text "[object Object]", and the parser read the "o" at position 1. The fix is not to parse it at all — it is already a parsed object.

Why does my JSON work in one language but not another?

Parser leniency varies. Python accepts NaN and Infinity by default; some parsers tolerate trailing commas or comments; others are strict. A document that only works in one place is not portable JSON, and it will break the first time something else consumes it.

How do I find an error in a 10,000-line JSON file?

Use the character position from the error rather than reading. Format the document first so the position maps to a line you can see, then look at the token immediately before the one named — the parser reports where it failed, which is usually just after the mistake.

Can any invalid JSON be repaired automatically?

The structural mistakes can: quote style, unquoted keys, trailing commas, missing commas between containers. Truncation cannot, because the missing data is genuinely absent, and neither can NaN or Infinity, because JSON has no way to represent them. Automatic repair is a shortcut for hand-written documents, not a substitute for fixing a broken producer.

Does JSON allow comments if I only use the file locally?

The format does not, whatever the file is for. A parser that accepts comments is being lenient beyond the specification, and the document will fail the moment anything strict reads it. If you need comments in a config file, use JSON5, JSONC, YAML or TOML deliberately rather than hoping.

The short version

Work from the character position, look at the token before the one the parser names, and check the four usual suspects first: trailing comma, single quotes, unquoted key, unescaped character in a string. If the message says the input ended unexpectedly, suspect an empty response before you suspect the JSON. And if the document looks flawless, suspect a byte-order mark — it is invisible, it is at position 0, and it fools everyone once.

Tools that go with this

Each one is here for a specific reason rather than because it is in the same category.

Popular

JSON Formatter

Format, validate, and beautify JSON online

Open Tool

Reports the failing line and will repair the common structural mistakes without touching your string contents.

JSON Escape / Unescape

Escape and unescape JSON strings

Open Tool

The fix for the whole class of errors caused by unescaped quotes, backslashes and newlines inside strings.

New

YAML ↔ JSON Converter

Bidirectional YAML and JSON conversion with error reporting

Open Tool

Useful when the thing you were handed turns out to be YAML rather than the JSON you were promised.

New

CSV to JSON Converter

Convert CSV data to JSON arrays instantly in your browser

Open Tool

For the other common mislabelling — a CSV export that arrived with a .json extension.

Sources

  1. JSON.parse() — JavaScript reference

    MDN Web Docs · Technical documentation · accessed 7 September 2026

    Cited for: The SyntaxError raised for invalid JSON, and the worked trailing-comma and single-quote failures

  2. RFC 8259 (STD 90) — The JavaScript Object Notation (JSON) Data Interchange Format

    IETF · Standards organisation · published 1 December 2017 · accessed 7 September 2026

    Cited for: The four permitted whitespace characters, the mandatory string escapes, and the UTF-8 encoding requirement behind the BOM problem

  3. ECMA-404, 2nd edition — The JSON Data Interchange Syntax

    Ecma International · Standards organisation · published 1 December 2017 · accessed 7 September 2026

    Cited for: That the grammar is defined exhaustively — the basis for saying a comment or a NaN literal cannot be valid JSON however lenient a parser is

About the author

toolforge.website

Builder and maintainer, ToolForge

Started ToolForge in May 2026 and has built and maintained it since, writing every tool on the site and the documentation that goes with each one.

How we research and check this content · About ToolForge

Part of

JSON

What JSON is, the syntax rules that actually trip people up, why a parser rejected your file, and how JSON compares with XML and YAML.

Browse all developer tools
Buy Me a Coffee