JSON Validator

Output
Indent:
Examples:

Last updated: 2026-09-17

Paste JSON to instantly check if it is valid. On error, you get the exact line and column, a plain-English explanation of what went wrong, and a one-click Repair button. Everything runs locally — no server calls.

What this tool does

Validates JSON input against the RFC 8259 specification. On success, it shows a green confirmation. On failure, it reports the exact line and column where the error occurs, plus a plain-English explanation of the cause. A custom position scanner walks the input token by token to pinpoint the error location accurately.

Example

Input with a trailing comma:

{
  "name": "test",
  "value": 42,
}

Output:

Trailing comma on line 3, column 1. JSON doesn't allow commas after the last item in an object or array.

Input with single quotes:

{'name': 'test', 'active': True}

Output:

Unexpected character on line 1, column 1. You may have used single quotes instead of double quotes, or forgotten to quote a key.

Common JSON errors and fixes

ErrorBrokenFixed
Trailing comma{"a":1,}{"a":1}
Single quotes{'a':1}{"a":1}
Unquoted keys{name:"test"}{"name":"test"}
Missing closing brace{"a":[1,2]{"a":[1,2]}
Extra closing brace{"a":1}}{"a":1}
Multiple top-level values{"a":1}{"b":2}[{"a":1},{"b":2}]
Python booleans{"active":True}{"active":true}
Comments{"a":1 // comment}{"a":1}

Each error is reported with the line and column where the parser stopped, and a plain-English explanation of the cause.

Validating API responses

When a backend endpoint returns malformed JSON, the first step is to find where the syntax breaks. Paste the raw response body into the validator and read the reported line and column.

A typical broken response from a paginated user list:

{
  "page": 2,
  "perPage": 25,
  "users": [
    {"id": 1042, "name": "Avery Lin", "role": "admin",},
    {"id": 1043, "name": "Jordan Park", "role": "editor"}
  ],
  "total": 1890
}

The validator reports a trailing comma on line 5. The serializer that produced this output wrote a comma after the last element of the first user object. Fixing the source serializer is the real solution, but the reported position tells you exactly which record to inspect in the response stream.

For responses fetched with fetch in the browser, wrap the call so that a parse failure surfaces the raw text for pasting here:

const res = await fetch('/api/users?page=2');
const raw = await res.text();
try {
  const data = JSON.parse(raw);
  console.log(data);
} catch (e) {
  console.error('Parse failed. Raw body for the validator:\n', raw);
}

Catching the error and logging the raw text matters because res.json() throws the same message but discards the body, leaving you with no text to diagnose.

Validating configuration files

Configuration files are a common source of JSON syntax errors because they are hand-edited. A settings file for a build pipeline might look valid at a glance but fail on a single missing quote:

{
  "build": {
    "output": "dist",
    "assets": ["fonts", "images", "icons"],
    "minify: true,
    "sourcemap": false
  }
}

The validator reports an unexpected token around line 4. The key minify is missing its closing double quote, so the parser treats minify: true as a string value that runs into the colon. The plain-English explanation points to the column where the parser gave up, which is usually close to the actual typo.

Environment-specific overrides are another frequent source of errors. When you merge a base config with an environment override by hand, mismatched brackets and extra commas appear often. Validate the merged result before saving it, rather than waiting for the application to crash on startup with a less helpful stack trace.

Understanding error messages

Every error message has two parts: a short label that names the problem, and a sentence that explains the cause in plain English. Both reference the line and column where the scanner stopped.

Trailing comma. A comma appears after the last item in an object or array. JSON forbids trailing commas even though JavaScript and Python allow them. The message names the line and column of the comma so you can delete it directly. This is the most common error when editing JSON by hand, because adding a new property on a new line with a comma feels natural but breaks the last line.

Single quotes. String values and keys must use double quotes. Single quotes are valid in JavaScript object literals but not in JSON. The scanner reports an unexpected character at the position of the first single quote. The explanation suggests switching to double quotes or checking for an unquoted key, since both produce the same initial character mismatch.

Unquoted keys. Object keys must be wrapped in double quotes. Writing {name: "test"} is valid JavaScript but invalid JSON. The scanner reports an unexpected token at the key position because the parser expects a string but finds a bare identifier instead. The fix is to wrap every key in double quotes.

Multiple top-level values. Standard JSON allows exactly one top-level value: one object, one array, or one primitive. Pasting two objects back to back, such as {"a":1}{"b":2}, triggers a “Multiple JSON values” error at the position of the second opening brace. This often happens when concatenating log lines or streaming chunks into a single buffer. The fix is to wrap the values in an array or validate them one at a time.

Truncated input. When the input ends before all open braces and brackets are closed, the scanner reports that the JSON is truncated or incomplete. The reported line is the last line of the input, not the location of the missing brace, because the parser runs out of text before it can find the closing token. Common cause: a network request or file read was cut off mid-stream, or a copy-paste dropped the final characters.

Unexpected tokens. A catch-all for characters the parser did not expect at a given position: a colon where a comma belongs, a keyword like True or None from Python, a bare number where a string is required, or a stray bracket. The explanation describes what the parser expected versus what it found, so you can decide whether the character is a typo or a structural mistake.

Common mistakes when writing JSON

How the position scanner works

The validator first calls the built-in JSON.parse on the input. When JSON.parse succeeds, the input is valid and the tool reports success. When JSON.parse throws, the built-in error message is vague: it names an unexpected token and a character offset, but the offset is not always accurate and the message never explains the cause in plain English.

To produce a useful report, the tool runs a second pass with a custom findErrorPosition scanner. The scanner walks the input character by character and tracks the structure of the document as it goes: it records whether it is inside a string, inside an object, or inside an array, and it maintains a stack of open brackets and braces. As it advances, it classifies each token it encounters.

When the scanner reaches a token that violates the grammar, it stops and records the character offset. It then converts that offset into a line number and a column number by counting newline characters up to that point. The line is one-based and the column is one-based, matching the convention of most text editors, so the reported position jumps directly to the right spot in your editor.

Because the scanner tracks context, it can distinguish between a trailing comma and a missing comma, and between a single-quoted string and an unquoted key. The same character can mean different things depending on whether the scanner is inside a string or at a structural position. This is why the tool reports “Trailing comma” for a comma after the last item but “Unexpected character” for a single quote at the start of a key.

Once the scanner has the position and the token classification, the explainError function maps the finding to a plain-English sentence. The explanation describes what the parser expected at that position and what it found instead, so you can fix the input without reading the JSON grammar.

The validator is one step in a JSON editing workflow. Pair it with the other tools depending on what you need:

A typical sequence: validate to confirm the input is broken, read the reported position, try a manual fix, validate again. If the errors are repetitive or the file is large, send it to JSON Repair and review the changes before trusting the output.

Validating JSON in automated tests

Test suites that compare API output against expected JSON fixtures are sensitive to format drift. A test that loads a fixture file and parses it will throw an opaque error if the fixture has a syntax error, and the stack trace rarely points at the offending line.

A practical pattern is to validate fixtures during test setup, before the assertions run:

import json, pathlib, pytest

@pytest.fixture(scope="session")
def user_fixture():
    text = pathlib.Path("fixtures/user.json").read_text()
    try:
        return json.loads(text)
    except json.JSONDecodeError as e:
        pytest.fail(f"fixture user.json is invalid: {e.msg} at line {e.lineno}, column {e.colno}")

Running the fixture through a parser in setup turns a confusing assertion failure into a clear message that names the file, the error, and the position. In a continuous integration pipeline, a lint step that validates every committed JSON file catches broken fixtures before they reach the test stage.

In Jest, the equivalent guard uses a single expect before the describe block:

const fs = require('fs');
const fixture = fs.readFileSync('fixtures/user.json', 'utf8');
test('fixture parses', () => {
  expect(() => JSON.parse(fixture)).not.toThrow();
});

If that guard fails, the report names the file and the parse error instead of cascading into every downstream assertion.

Do it in code

JavaScript:

try {
  JSON.parse(input);
  console.log('Valid JSON');
} catch (e) {
  console.log('Invalid:', e.message);
}

Note: the built-in JSON.parse error message does not always include the position. This tool uses its own scanner to find the exact line and column.

Python:

import json
try:
    json.loads(input_string)
    print('Valid JSON')
except json.JSONDecodeError as e:
    print(f'Invalid: {e.msg} at line {e.lineno}, column {e.colno}')

Python’s json.JSONDecodeError includes line and column information by default.

CLI (jq):

echo "$input" | jq '.' > /dev/null
# Exit code 0 = valid, non-zero = invalid

Edge cases handled

Frequently asked questions

What makes JSON invalid?
Common causes: trailing commas, single quotes instead of double quotes, unquoted keys, comments (JSON does not support comments), or truncated input with missing closing braces. Each of these produces a different error message with the line and column where the parser stopped.
Why does JSON not allow comments?
The JSON specification (RFC 8259) does not include comments. If you need comments, use JSONC or JSON5 formats. Use the JSONC to JSON tool to strip comments from tsconfig.json or VS Code settings before validating them here.
Can I validate JSON5 or JSONC?
This validator checks strict standard JSON (RFC 8259). JSON5 and JSONC are separate formats with their own parsers. Use the JSONC to JSON tool to strip comments first, then validate the cleaned output here.
How accurate are the error locations?
The tool uses its own position scanner that walks the JSON token by token to find exactly where the syntax error occurs, then converts that offset to line and column numbers. The plain-English explanation tells you what went wrong at that position.
Does the validator store my data?
No. Validation happens entirely in your browser using the JavaScript engine. Your JSON is never sent to any server, logged, or stored. There is no backend — all processing is client-side.
What does the Repair button do?
Clicking Repair sends your broken JSON to the JSON Repair tool, which attempts to fix common issues automatically: trailing commas, single quotes, unquoted keys, truncated output, and Python-style booleans. It shows a list of fixes applied and the repaired output.
Can I validate very large JSON files?
The validator runs in your browser and uses the built-in JSON.parse engine, so the practical limit is the memory available to the browser tab. Multi-megabyte files generally work, but extremely large documents can make the tab slow or unresponsive. For huge payloads, consider splitting them or validating in a script using a streaming parser such as JSON.parse in Node or ijson in Python, which process data incrementally without loading the whole document into memory.
What is the difference between validation and repair?
Validation only checks your input and reports errors with the exact line and column. It never changes the content. Repair sends the broken input to the JSON Repair tool, which rewrites the text to fix common syntax problems and returns a corrected document. Use validation to find out what is wrong, then use repair when you want the tool to attempt an automatic fix. Repair is a best-effort transformation, so you should review the output afterward.

Related tools