Maximum Nesting Depth in JSON
Understand JSON nesting depth limits across parsers and platforms. Learn why deeply nested JSON causes stack overflows and how to set safe depth limits in your code.
Detailed Explanation
The JSON specification (RFC 8259) does not define a maximum nesting depth for objects and arrays. In theory, a JSON document can be nested thousands of levels deep. In practice, every parser has a limit determined by available stack memory, and deeply nested JSON can cause stack overflow errors, denial-of-service vulnerabilities, and performance degradation.
Why depth matters:
Most JSON parsers use recursive descent parsing, where each level of nesting adds a frame to the call stack. A document nested 10,000 levels deep requires 10,000 stack frames, which exceeds the default stack size in most environments. In JavaScript, the V8 engine typically allows 10,000-15,000 levels of recursion before throwing a RangeError: Maximum call stack size exceeded. In Python, the default recursion limit is 1,000, and json.loads() will hit it with deeply nested input.
Parser-specific limits:
- JavaScript (V8): ~10,000 levels before stack overflow
- Python (json module): ~1,000 levels (default recursion limit, adjustable with
sys.setrecursionlimit()) - Java (Jackson): Configurable, default 1,000 (
StreamReadConstraints) - Go (encoding/json): ~10,000 levels (limited by goroutine stack, which grows dynamically)
- PHP (json_decode): Configurable
depthparameter, default 512 - .NET (System.Text.Json): Configurable
MaxDepth, default 64
Security implications:
Deeply nested JSON is a classic denial-of-service vector. An attacker can send a small payload like [[[[[[[... (just opening brackets) that causes the server's JSON parser to exhaust its stack and crash. This is known as a "billion laughs" or "nested bomb" attack. Web application firewalls and API gateways should enforce depth limits on incoming JSON payloads.
Constructing deeply nested JSON:
Deeply nested structures usually arise from bugs rather than design choices. A recursive data structure that references itself, an unbounded tree traversal, or a serialization loop can all produce unexpectedly deep JSON. In rare legitimate cases (like serializing a file system tree or a deeply nested organizational hierarchy), consider flattening the structure with reference IDs instead.
Common mistakes developers make:
The most critical mistake is not setting explicit depth limits when parsing untrusted JSON. Using the default parser settings leaves your service vulnerable to stack overflow attacks. Another mistake is silently truncating deeply nested data during serialization, which can corrupt the output without any error. Developers also sometimes increase the stack size or recursion limit as a "fix" for depth issues, which merely raises the ceiling without addressing the underlying problem.
Best practices:
Set an explicit maximum depth limit (32 or 64 is reasonable for most applications) and reject input that exceeds it with a clear error message. Use iterative (non-recursive) parsers for high-security contexts. Design your data models to avoid unnecessary nesting — flatten hierarchies using reference IDs when depth exceeds 4-5 levels. Monitor and log rejected payloads to detect potential attacks.
Use Case
Configuring a web API's JSON parser with a maximum depth of 32 levels to prevent stack overflow denial-of-service attacks from maliciously crafted nested payloads.