What RFC 8259 & ECMA-404 Actually Say
The complete JSON specification reference — every rule explained with examples, spec citations, and a live validator.
The Two JSON Specifications
JSON has two authoritative specifications that coexist without contradiction. The first is RFC 8259, published by the IETF in December 2017, which obsoletes earlier RFCs (4627 and 7159) and is the current internet standard for JSON. The second is ECMA-404, maintained by ECMA International, which defines the core JSON data interchange syntax. The two documents are designed to be consistent with each other: ECMA-404 defines the grammar, RFC 8259 adds internet-specific guidance on encoding and interoperability.
Together, these documents define a format that is deliberately minimal. JSON has no comments, no optional syntax, and no extensions. Every parser that claims to be conformant must accept the same inputs and reject the same invalid inputs. This strictness is both a feature and a frequent source of confusion for developers who write JSON by hand.
Paste your JSON below to check it against the spec. The checker identifies violations by type and links them directly to the relevant section.
JSON Spec Compliance Checker
The key "name" is not quoted. JSON requires all object keys to be double-quoted strings.
JSON strings must use double quotes. Replace single quotes with double quotes.
JSON does not support comments. Remove this comment or use a dedicated field for documentation.
The key "tags" is not quoted. JSON requires all object keys to be double-quoted strings.
JSON does not allow a trailing comma after the last element in an object or array.
JSON does not allow a trailing comma after the last element in an object or array.
Strings Must Use Double Quotes (RFC 8259 §7)
Section 7 of RFC 8259 defines the string grammar precisely. A JSON string begins and ends with a U+0022 QUOTATION MARK character — the double quote. Single quotes, backticks, and bare (unquoted) strings are not part of the grammar and will cause any conformant parser to reject the document.
“A string is a sequence of zero or more Unicode characters wrapped in quotation marks, using backslash escapes.” — RFC 8259, Section 7
This rule applies to both values and keys. Because JavaScript and Python both accept single quotes for string literals, hand-written JSON frequently contains them — and frequently fails to parse.
// INVALID — single quotes are not JSON
{ 'name': 'Alice', 'role': 'admin' }
// VALID — double quotes required
{ "name": "Alice", "role": "admin" }The reason for requiring double quotes (rather than either type interchangeably) is simplicity: a format with a single valid delimiter is easier to parse and easier to generate deterministically. Douglas Crockford has noted that the choice was deliberate — making JSON a strict subset of JavaScript object notation by using only the form that JavaScript already required for property names in certain contexts.
Object Keys Must Be Strings (RFC 8259 §4)
Section 4 of RFC 8259 defines the object grammar. An object is a collection of zero or more name/value pairs. The name in each pair must be a string — that is, it must be a double-quoted sequence of characters. Unquoted identifiers, numbers, and boolean literals are not valid as object keys in JSON, even though JavaScript object literals permit them.
“An object structure is represented as a pair of curly brackets surrounding zero or more name/value pairs (or members). A name is a string.” — RFC 8259, Section 4
// INVALID — unquoted keys
{ name: "Alice", age: 30, 0: "zero" }
// VALID — all keys are double-quoted strings
{ "name": "Alice", "age": 30, "0": "zero" }This rule has a practical consequence: two JSON objects can have identical keys that differ only in how they would be interpreted as identifiers. For example, "true" and "false" are perfectly valid JSON object keys, even though they look like boolean values. If you are generating JSON from a language where object keys can be non-strings, you must explicitly convert them.
Comments Are Not Allowed (ECMA-404 / RFC 8259)
JSON has no comment syntax. Neither // line comments nor /* */ block comments are part of the grammar. This is one of the most commonly asked questions about JSON, and the answer is unambiguous: comments are invalid.
// INVALID — comments are not allowed in JSON
{
// database configuration
"host": "localhost",
"port": 5432 /* default PostgreSQL port */
}
// VALID — no comments
{
"host": "localhost",
"port": 5432
}Douglas Crockford, who designed JSON, has explained this decision publicly: he removed comments from an early draft because he observed that people were using them to embed parsing directives — annotations that instructed different parsers to behave differently. Removing comments kept JSON purely interoperable. If a format needs comments, it needs to be a different format.
Practical alternatives exist. JSONC (JSON with Comments) is used by VS Code for configuration files and supports both comment styles. JSON5 is a superset of JSON that adds comments, trailing commas, and single quotes, among other extensions. If you need comments in configuration files, consider YAML, which supports comments natively and is designed for human-edited configuration. None of these formats is valid JSON — parsers that accept JSONC or JSON5 are operating in a non-standard mode.
No Trailing Commas (RFC 8259 §4-5)
The grammar productions in Sections 4 (objects) and 5 (arrays) of RFC 8259 define separators using a value-separator token that appears between elements, not after the last one. A trailing comma — a comma immediately before a closing brace or bracket — is therefore outside the grammar and constitutes a parse error.
“[An array is] begin-array [ value *( value-separator value ) ] end-array” — RFC 8259, Section 5 (ABNF grammar)
// INVALID — trailing comma in object
{
"name": "Alice",
"role": "admin",
}
// INVALID — trailing comma in array
["epoch", "cron", "json",]
// VALID
{
"name": "Alice",
"role": "admin"
}
// VALID
["epoch", "cron", "json"]This trips up JavaScript and TypeScript developers in particular. ES5 introduced legal trailing commas in JavaScript object literals and array literals, and TypeScript follows suit. Modern linters even enforce trailing commas as a style preference because they produce cleaner diffs. The habit of always adding a trailing comma is completely valid in JavaScript source code — and completely invalid in JSON.
Number Format Restrictions (RFC 8259 §6)
Section 6 of RFC 8259 specifies the number grammar. JSON numbers have several restrictions that differ from JavaScript number literals and from common programming conventions:
- No leading zeros:
08080is invalid. The grammar permits0alone or0.something, but not08080. (Leading zeros suggest octal in many languages, and JSON avoids ambiguity by prohibiting them.) - No hexadecimal notation:
0xFFis invalid. JSON numbers are always in decimal. - No NaN or Infinity: The special IEEE 754 values
NaN,Infinity, and-Infinityare not representable in JSON. They are valid in JavaScript but are not in the JSON number grammar. APIs that need to represent these values typically usenullor a sentinel string. - No leading plus sign:
+1is not a valid JSON number. The grammar permits a leading minus sign (-1) but not a leading plus.
// INVALID
{ "port": 08080 } // leading zero
{ "mask": 0xFF } // hexadecimal
{ "ratio": NaN } // NaN not in grammar
{ "limit": Infinity } // Infinity not in grammar
{ "offset": +10 } // leading plus not allowed
// VALID
{ "port": 8080 }
{ "mask": 255 }
{ "ratio": null }
{ "limit": 1e9 }
{ "offset": 10 }Escape Sequence Rules (RFC 8259 §7)
Section 7 of RFC 8259 enumerates exactly eight single-character escape sequences that are valid inside a JSON string, plus a Unicode escape form. Every other backslash sequence is invalid:
"\""— quotation mark (U+0022)"\\"— reverse solidus / backslash (U+005C)"\/"— solidus / forward slash (U+002F)"\b"— backspace (U+0008)"\f"— form feed (U+000C)"\n"— line feed (U+000A)"\r"— carriage return (U+000D)"\t"— tab (U+0009)"\uXXXX"— Unicode escape, four hex digits
Notably absent: \x41 (hex escape for a single byte) is valid in JavaScript strings but not in JSON. Similarly, \' (escaped single quote) has no special meaning in JSON and is invalid as an escape sequence. Control characters in the range U+0000 through U+001F must be escaped using \uXXXX notation — they cannot appear unescaped in a JSON string.
// INVALID — \x escape not in JSON grammar
{ "char": "\x41" }
// INVALID — \' has no meaning in JSON
{ "note": "it\'s a test" }
// VALID — use \uXXXX for Unicode, or just the character directly
{ "char": "\u0041" }
{ "note": "it's a test" }Encoding: UTF-8 Required (RFC 8259 §8.1)
Earlier versions of the JSON standard (RFC 4627 and RFC 7159) permitted JSON text to be encoded in UTF-8, UTF-16, or UTF-32, and relied on a BOM or byte-order detection to determine the encoding. RFC 8259 tightens this rule significantly.
“JSON text exchanged between systems that are not part of a closed ecosystem MUST be encoded using UTF-8.” — RFC 8259, Section 8.1
For JSON used over the internet — APIs, webhooks, configuration files fetched over HTTP — UTF-8 is the only compliant encoding. Furthermore, RFC 8259 §8.1 states that implementations MUST NOT add a byte order mark (BOM) to the beginning of a JSON text, and parsers that encounter a BOM may reject it. This is a change from RFC 4627, which permitted BOMs. If you are working with JSON received from a system that adds a UTF-8 BOM (EF BB BF at the start of the file), that is a spec violation in the context of RFC 8259.
JSON vs JavaScript Object Literals
JSON is often described as a subset of JavaScript, but the relationship is more nuanced. JSON is a subset of JavaScript in the sense that every valid JSON document is a valid JavaScript expression — but the reverse is not true. JavaScript object literals have many features that are not available in JSON:
| Feature | JSON | JavaScript Object Literal |
|---|---|---|
| Single-quoted strings | No | Yes |
| Unquoted keys | No | Yes |
| Trailing commas | No | Yes (ES5+) |
| Comments | No | Yes |
undefined values | No | Yes |
Hexadecimal numbers (0xFF) | No | Yes |
NaN / Infinity | No | Yes |
This table explains why copying a JavaScript object literal into a JSON file so often fails. The most reliable workflow is to generate JSON programmatically using JSON.stringify() rather than writing it by hand, and to validate the result using our JSON Formatter before shipping it.
Common Error Messages Explained
When a JSON parser encounters a violation, the error message it produces depends on the runtime and how far the parser got before failing. Here are the most common messages and the spec rules they map to:
- “Unexpected token ' in JSON at position 0” — The parser encountered a single quote before any other valid token. This maps to the double-quote rule (RFC 8259 §7). The most common cause is pasting a JavaScript object literal with single-quoted keys or values.
- “Unexpected token '/' in JSON at position N” — The parser found a forward slash that is not part of a valid escape sequence or string. This typically indicates a comment (RFC 8259 / ECMA-404). Both
//and/* */comments trigger this error. - “Unexpected token '}' in JSON at position N” or “Unexpected non-whitespace character after JSON” — Often caused by a trailing comma (RFC 8259 §4-5). The parser successfully reads the last value, then finds a comma and expects another value, but instead finds the closing brace.
- “Unexpected token 'n' (or any identifier) in JSON at position N” — An unquoted key (RFC 8259 §4) was encountered. The parser expected a double-quoted string or the closing brace, but found a bare identifier.
- “Unexpected number in JSON at position N” — A number with a leading zero or a leading plus sign was encountered, violating the number format rules (RFC 8259 §6).
- “Bad escaped character in string at position N” or “Invalid escape character” — An invalid backslash sequence like
\xor\pwas encountered, violating the escape sequence rules (RFC 8259 §7).
Further Reading
- RFC 8259 — The JSON Data Interchange Format
The current IETF internet standard for JSON, including encoding requirements and interoperability guidance.
- ECMA-404 — The JSON Data Interchange Syntax
The ECMA International standard defining the core JSON grammar with railroad diagrams.
- JSON Syntax Guide: Common Errors and How to Fix Them
A practical guide to the most common JSON parse errors and step-by-step fixes.