JSON Validator
100% in your browser
Your data is never uploaded. All processing happens locally on your device.
Read privacy policy →Keyboard shortcuts
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
| Error | Broken | Fixed |
|---|---|---|
| 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
Trailing commas after the last item. Adding a comma to the final property of an object or the final element of an array is the single most frequent hand-editing mistake. JSON has no tolerance for trailing commas, unlike JavaScript and Python. After appending a property, check whether the previous line already ended with a comma.
Single quotes instead of double quotes. Copying a JavaScript object literal into a JSON file is a reliable way to introduce single quotes. JSON requires double quotes for every string and every key. Run a find-and-replace for single quotes before validating.
Unquoted object keys. Shorthand keys like
{port: 8080}are convenient in code but invalid in JSON. Every key needs double quotes around it, with no exceptions for short names or numeric-looking identifiers.Comments left in the file. JSON has no comment syntax. Lines starting with
//or wrapped in/* */cause parse failures. Move documentation into a sibling markdown file or switch to JSONC if you need inline notes, then strip the comments with the JSONC to JSON tool before validating here.Python-style booleans and null. Python writes booleans as
TrueandFalseand the empty value asNone. JSON requires lowercasetrue,false, andnull. When exporting data from a Python script, serialize withjson.dumpsrather thanreprorstrto get the correct casing automatically.Multiple root values in one document. Pasting several JSON objects into one file, separated by newlines, is valid in JSON Lines format but not in standard JSON. Either validate each line separately or wrap the collection in a top-level array.
Missing or extra closing brackets. Deeply nested objects make it easy to drop a closing brace or add an extra one. The scanner reports truncation when a brace is missing and an unexpected token when one is extra. Matching indentation by hand before validating catches most of these.
Control characters inside strings. Literal tab or newline characters inside a string value are invalid. JSON requires escape sequences like
\tand\ninstead. Text pasted from a spreadsheet or terminal often carries hidden control characters that surface as unexpected token errors.
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.
Related tools
The validator is one step in a JSON editing workflow. Pair it with the other tools depending on what you need:
- JSON Formatter — takes valid but minified JSON and adds indentation and line breaks so it is readable. Validate first, then format, because a formatter will refuse to prettify input that fails to parse.
- JSON Minifier — the reverse operation. It strips whitespace and newlines from valid JSON to shrink the byte size for network transfer. Again, validate before minifying so you do not ship broken payloads.
- JSONC to JSON — removes comments and trailing commas from JSONC input (TypeScript configs, VS Code settings) and outputs strict JSON suitable for this validator.
- JSON Repair — the destination of the Repair button. Accepts broken input and applies a set of heuristics to produce valid JSON. Use it when validation shows errors you do not want to fix by hand.
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 = invalidEdge cases handled
- Trailing commas are detected and the error message says “Trailing comma” with the correct line and column.
- Single quotes and unquoted keys produce “Unexpected character” with guidance to use double quotes.
- Multiple top-level values (e.g.
{"a":1}{"b":2}) produce “Multiple JSON values” with the position of the second value. - Truncated input produces “The JSON is truncated” or “The input is incomplete” with the line where it ended.
- Empty input is handled gracefully without crashing.