How to Validate JSON: Syntax Errors, Schemas and Common Mistakes
Find and fix JSON syntax errors, catch duplicate keys and big-number pitfalls, and validate structure with JSON Schema in JavaScript, Python and CI pipelines.
By the koducat teamUpdated 6 min read
Two kinds of JSON validation
"Valid JSON" can mean two different things, and it helps to keep them apart:
- Syntax validation asks whether the text is well-formed JSON according to RFC 8259 — balanced brackets, double-quoted strings, commas in the right places. Any JSON parser can answer this.
- Schema validation asks whether well-formed JSON has the structure your application expects — required fields present, values of the right type, numbers in range. That needs a description of the expected shape, usually a JSON Schema.
A document can pass the first check and fail the second: {"age": "forty"} is perfectly valid JSON but probably not valid data. Most production bugs involving JSON are of this second kind, so it is worth setting up both checks.
Where you validate matters as much as how. Validate at system boundaries — when a request reaches your API, when a config file is read at startup, when a message is consumed from a queue — and fail fast with a clear error. Data that has passed validation at the edge can then be trusted by the rest of your code, instead of every function re-checking types defensively.
How to validate JSON online
- Paste the document into the JSON Validator, or load the sample to see what a report looks like.
- Click Validate. A valid document shows a success message along with structure statistics such as depth and key counts.
- If it is invalid, read the line and column in the error message and look at the highlighted line. Fix the first error and validate again — one mistake can confuse a parser about everything after it.
- Check the duplicate-key report. Duplicates are legal syntax but almost always a mistake.
- To check structure as well, paste the document and a schema into the JSON Schema Validator.
Working with line-delimited files such as logs or datasets? Use the JSONL Validator, which checks each line independently and reports problems per line.
The most common JSON syntax errors
JSON looks like JavaScript object syntax, but it is much stricter. Almost every syntax error comes from a JavaScript habit or from hand-editing:
| Mistake | Example | Why it fails |
|---|---|---|
| Trailing comma | [1, 2, 3,] | JSON does not allow a comma after the last element or member |
| Single quotes | {'name': 'Ada'} | Strings and keys must use double quotes |
| Unquoted key | {name: "Ada"} | Every object key must be a string |
| Comments | // ... or /* ... */ | JSON has no comment syntax |
| Special numbers | NaN, Infinity, undefined | Not JSON values; use null or a string |
| Leading zeros | {"code": 007} | Numbers cannot start with 0 unless the number is 0 or 0.x |
| Unescaped control characters | A tab or newline inside a string | Must be written as \t or \n |
| Invalid escape | "C:\path" | Backslashes must be doubled: "C:\\path" |
Validating JSON syntax in code and on the command line
function parseJsonSafe(text: string): { ok: true; value: unknown } | { ok: false; error: string } {
try {
return { ok: true, value: JSON.parse(text) };
} catch (err) {
return { ok: false, error: (err as SyntaxError).message };
}
}JSON.parse error messages differ between JavaScript engines: some include a character position, others only describe the unexpected token. If you need consistent line and column numbers for users, compute them from the position yourself or use a parser that reports them, as the validator on this site does.
Python's JSONDecodeError gives you the line and column directly:
import json
try:
data = json.loads(text)
except json.JSONDecodeError as e:
print(f"Invalid JSON at line {e.lineno}, column {e.colno}: {e.msg}")# jq exits with a non-zero status on invalid input
jq empty config.json && echo "valid"
# Validate every JSON file in a repository (fails the CI job on the first error)
find . -name '*.json' -not -path './node_modules/*' -print0 \
| xargs -0 -n1 python3 -m json.tool > /dev/nullValidating structure with JSON Schema
JSON Schema is a vocabulary for describing JSON documents, itself written in JSON. The current published version is draft 2020-12. A schema states the type of each value, which properties are required, and constraints such as minimum lengths or allowed values:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["id", "email"],
"properties": {
"id": { "type": "integer", "minimum": 1 },
"email": { "type": "string", "format": "email" },
"role": { "enum": ["admin", "editor", "viewer"] }
},
"additionalProperties": false
}In JavaScript, Ajv is the most widely used validator. Note that Ajv does not check format keywords such as email unless you add the ajv-formats plugin:
import Ajv2020 from "ajv/dist/2020";
import addFormats from "ajv-formats";
const ajv = new Ajv2020({ allErrors: true });
addFormats(ajv);
const validate = ajv.compile(schema);
if (!validate(data)) {
for (const err of validate.errors ?? []) {
console.log(`${err.instancePath || "(root)"} ${err.message}`);
}
}from jsonschema import Draft202012Validator # pip install jsonschema
validator = Draft202012Validator(schema)
for error in validator.iter_errors(data):
print(list(error.path), error.message)You can try schemas interactively in the JSON Schema Validator before adding them to your code. If you have sample data but no schema yet, generating types with JSON to TypeScript is a quick way to see the shape you are dealing with.
Subtle problems that syntax checks miss
- Duplicate keys.
{"a": 1, "a": 2}parses without error in most languages, which silently keep one value (usually the last). Different parsers may pick different values, which has caused real security bugs. Reject duplicates at the source. - Large integers. JavaScript and many JSON libraries store numbers as 64-bit floats, so integers above 9,007,199,254,740,991 lose precision. Send 64-bit IDs as strings.
- Encoding. RFC 8259 requires UTF-8 for JSON exchanged between systems. A byte-order mark at the start of a file is tolerated by some parsers and rejected by others.
- Empty input. An empty string is not valid JSON. APIs that return an empty body with
Content-Type: application/jsonmakeresponse.json()throw. - Look-alike formats. JSON5, JSONC (JSON with comments) and YAML all look similar but are different formats. Use the matching parser — for YAML files, the YAML Validator.
For formatting tips once your JSON validates, see How to Format JSON Online. All JSON utilities are listed in the JSON tools category.
Try it now with the free JSON Validator — it runs in your browser.
Open JSON ValidatorFrequently asked questions
Why does my JSON fail to validate when it works in JavaScript?
JavaScript object literals allow single quotes, unquoted keys, trailing commas, comments and values like undefined. JSON allows none of these. Code that works as a JavaScript literal can still be invalid JSON.
Are duplicate keys valid JSON?
RFC 8259 says object names should be unique but does not forbid duplicates, so most parsers accept them and keep one value. Because behaviour differs between parsers, treat duplicates as an error in your own data.
What is the difference between JSON validation and JSON Schema validation?
JSON validation checks syntax — whether the text can be parsed. JSON Schema validation checks the parsed data against rules about types, required fields and allowed values. You need both for reliable input handling.
Which JSON Schema draft should I use?
Use draft 2020-12 for new schemas unless a tool you depend on only supports an older draft. Declare it with the $schema keyword so validators know which rules to apply.