Summary

  • RFC 9535 standardizes how a JSONPath query selects a nodelist from one JSON value. Every selected node has exactly one Normalized Path in that value.
  • That path is a location, not a durable identity. Insert an item before $['approvals'][3], and the same path can name a different approval in the next document.
  • Empty results, JSON null, duplicate selections and out-of-range indexes are distinct states. A decision system must preserve the input, query, implementation, result and policy that gave the match its meaning.

At 09:00, $['approvals'][3] identifies the fourth approval in a JSON response. At 09:05, an older approval is inserted at the front. The path is still perfectly well formed; it still selects exactly one node; it now points to someone else.

Nothing in that sequence violates RFC 9535. The mistake is to treat a precise coordinate as though it were the enduring identity of the thing found there.

Published on the IETF Standards Track in February 2024, RFC 9535 supplies the common semantics that the once-fragmented JSONPath ecosystem lacked. A query runs against one JSON value—the query argument—and produces a nodelist containing zero or more nodes. A node combines a value with its location in that particular input. The standard makes that selection layer portable. It does not turn the input into an authenticated register or the selected node into a business fact.

One value, one canonical route to a node

A Normalized Path uses canonical bracket notation and escaping to identify exactly one node. For any node in a particular value, there is exactly one such path. That property is excellent for test fixtures, result comparison, post-processing and explicit duplicate removal. It lets an operator say, without hand-waving, which location an implementation selected.

The qualifier “in a particular value” carries the governance burden. A Normalized Path has no document digest, version, source, schema or stable object identifier embedded in it. Even a singular query can depend on the concrete input: a negative array index may select one node, while the corresponding Normalized Path records the resolved non-negative position. Change the array length and the apparent identity shifts.

JSON Pointer, RFC 6901, is another useful location mechanism, and RFC 9535 explains how a Normalized Path can be converted to a pointer. Conversion does not create persistence. Both notations need the same frozen structure if they are to refer to the same logical thing.

“Nothing selected” is not one diagnosis

RFC 9535 treats an empty nodelist as a valid result. A valid segment that asks for an out-of-range array index simply selects fewer nodes; later segments then continue from an empty set. That is operationally different from a malformed query, a timeout, a resource-limit failure or a parser rejection.

It is also different from JSON null. Null is a present JSON value. A missing member produces no node. If an access rule collapses both cases into a generic false value, the query engine may be correct while the policy becomes wrong.

Duplicate selections remain in the nodelist. count() counts nodes, not unique values, unique paths or unique business objects. And where the semantics allow more than one ordering, successive evaluations may return different permissible orders. “First match wins” is therefore an application rule, not a fact supplied by JSONPath, unless the surrounding contract independently defines the order.

Interoperability narrows mechanics, not meaning

RFC 8259 defines JSON and warns that duplicate object member names reduce interoperability. I-JSON, RFC 7493, narrows some of that unpredictability. RFC 9485 gives match() and search() a portable regular-expression profile. The live IANA JSONPath registry records extension functions, while the registered application/jsonpath media type gives query documents a common label.

These are valuable agreements. They make it more likely that two conforming systems select the same nodes from a well-behaved input. They do not say that an owner field names the legal owner, that a risk score is fresh, that a document came from an authorized source, or that a selected flag permits an irreversible action.

That distinction appears in a concrete neighbouring standard. RFC 9537 uses JSONPath to locate redacted fields in an RDAP response. The path can accurately locate the redaction assertion in that response. It cannot disclose the hidden value, establish the policy that authorized redaction or prove what an earlier response contained.

The security boundary starts before the dollar sign

RFC 9535 warns against passing query fragments to a host-language eval, and against unsafe interpolation of member names, indexes or comparison values. Crafted inputs can also drive naïve recursive processing toward excessive CPU use or stack exhaustion. Correct syntax therefore needs bounded execution, validated variables and an implementation that actually parses JSONPath rather than executing another language.

Encoding and data-model safeguards matter here. UTF-8, RFC 3629, and the implementation considerations referenced through CBOR, RFC 8949, help bound representation. But the decision chain is longer:

source bytes → parsed value → query → implementation and extensions → nodelist → application interpretation → decision

RFC 9535 disciplines the middle. A defensible receipt must bind the rest.

Preserve the receipt that makes a match useful

For a consequential use—access control, compliance, routing policy or incident triage—retain the source bytes or their cryptographic digest and provenance; parser and duplicate-name policy; exact query bytes and media type; interpolated variables before and after validation; implementation and version; enabled extension functions; timeout and resource limits; returned Normalized Paths and permitted values; post-query deduplication; any independent ordering rule; schema and policy version; and the actor, timestamp and outcome of the decision.

That record supports a bounded statement: implementation X evaluated query Q against input digest H and returned these locations under these limits. It does not support “this is the same record as yesterday” unless the schema supplies a stable ID and the evidence links that ID across versions.

Sources and limits

The primary publication record is available as HTML, plain text, the RFC Editor information page, the IETF Datatracker entry, its history and the errata search. Development history is visible in the IETF JSONPath working repository, and the independent JSONPath comparison project illustrates why a common standard was needed.

The analysis also uses RFCs 8259, 7493, 9485, 6901, 8949, 3629 and 9537, plus the IANA registry and media-type record.

The governance lens follows Heng Lu’s essays on reality layers and symbolic power, minimum initial specification and running-code primacy. No named implementation, service, incident or exploit was examined. The article does not claim that RFC 9535 is defective or that a particular deployment misuses it.