Blog · July 21, 2026 · Knox Hutchinson
gNMI Won Telemetry. RESTCONF Still Deserves QUERY.
- The Part Where You Should Probably Just Use gNMI
- What’s Actually Left for RESTCONF
- RESTCONF’s Read Problem: Projection Without Selection
- Ninety Seconds on QUERY (RFC 10008)
- The Sketch: A QUERY Binding for RESTCONF
- Saved Filters, Cheap Polls
- Deployment Economics, One More Time
- The Skeptic’s Section
- If You Want This to Exist
In June, HTTP grew its first new method since PATCH in 2010. RFC 10008 defines QUERY: a request that is safe and idempotent like GET, but carries a body like POST. It exists because “I need to send a complex query without changing anything, and it doesn’t fit in a URL” turned out to be one of the oldest unsolved problems in HTTP.
Network engineers have a specific, vivid version of that problem. It’s called RESTCONF.
Before anyone reaches for the comment box: no, this is not a “RESTCONF renaissance” post, and it is definitely not a gNMI alternative. Let’s do the concession first, properly — and then a design sketch for the lane that’s left.
The Part Where You Should Probably Just Use gNMI
If your question is “how do I get operational state off my fleet, fast and continuously,” the answer is gNMI and has been for years. gNMI isn’t even an IETF standard — the spec lives in OpenConfig’s GitHub — and it won anyway: streaming subscriptions with on-change semantics, protobuf on the wire, HTTP/2 multiplexing, and first-class support across IOS-XE and XR, NX-OS, Junos, EOS, and SR OS. If you’re building greenfield automation in an OpenConfig shop, close this tab and go run gnmic. This post will still be here.
That’s not a grudging concession; it’s the setup. gNMI won for the same reason QUIC won: the deployer and the beneficiary are the same party, and nobody had to ask permission. Hold that thought — we’ll run this post’s own proposal through the same test before the end.
So, plainly: nothing below competes with gNMI. Telemetry is settled. What follows is about a different, unglamorous lane — the plain-HTTPS lane — and making it suck less for the people already standing in it.
What’s Actually Left for RESTCONF
Honest sizing first: device-side RESTCONF adoption is thin, and “limited real-world implementations” is the polite consensus. But thin is not empty, and the places RESTCONF does live are load-bearing:
- Controller and orchestrator northbounds. Cisco NSO’s northbound API is RESTCONF — which quietly makes RESTCONF the highest-traffic YANG interface in a lot of SP and MSP shops that have never once pointed it at a router. OpenDaylight tells the same story.
- Enterprise IOS-XE fleets. Catalyst-class boxes have shipped RESTCONF for nearly a decade, and a decade of DevNet training built real tooling on it.
- The zero-toolchain long tail. The ITSM integration, the monitoring exporter, the compliance-report script: things that speak HTTPS+JSON from whatever language they woke up in, and will never — ever — carry protobuf codegen and a gRPC toolchain.
- Middlebox country. Plenty of enterprises still can’t get clean gRPC through their own inspection infrastructure. Port 443, JSON, request/response works everywhere the web works.
And underneath all of it, the ambient truth that never makes the conference slide: most real-world network “automation” is still SSH and screen-scraping. (We know. It’s our day job.) The HTTP lane is narrow — but it’s real, it isn’t going anywhere, and its worst part is fixable.
RESTCONF’s Read Problem: Projection Without Selection
RESTCONF reads are GET requests dressed in query parameters: fields for projection, depth to bound recursion, content to pick config vs. state, with-defaults. Within those limits, it’s fine.
Here’s what it can’t do: selection. There is no server-side way to say “give me the interfaces whose oper-status is down.” NETCONF has had this from the beginning — subtree filtering with content-match nodes, plus an optional XPath capability. RESTCONF’s filter query parameter looks like it should help, but read the fine print in RFC 8040 §4.8.4: it applies only to notification streams. For datastore reads you get projection, never selection.
So in practice you do one of three things, all bad:
- Over-fetch and filter client-side. Pull the whole interfaces tree — megabytes of JSON — to find three down ports. Rude against a 48-port switch; against a controller fronting thousands of devices, it’s a denial-of-service you schedule against yourself on a cron.
- Target exact instances and live in percent-encoding hell. Everyone who has typed
interface=GigabitEthernet0%2F0%2F0has felt the design fighting them — and a realfieldsexpression grows into a line of URL-encoded soup pushing against the request-target ceilings most servers and proxies enforce (commonly single-digit kilobytes). - Tunnel the read through POST. Wrap it in an RPC- or action-shaped endpoint. It works — and it quietly forfeits everything HTTP knows about reads: that they’re safe to retry on a dropped connection, that they’re cacheable, that an intermediary can tell them apart from writes.
Option 3 is the interesting one, because it’s a confession: the ecosystem already believes reads need a body. It just pays for that belief in semantics.
Ninety Seconds on QUERY (RFC 10008)
RFC 10008 — June 2026, Standards Track, the culmination of the HTTPBIS working group’s years-long “safe method with body” effort — gives that confession a legal home:
- A QUERY request asks the target resource “to perform a query operation within the scope of that target resource,” with the query carried in the request body and its semantics set by the media type.
- It is safe — the client “does not request or expect any change to the state of the target resource” — and idempotent: in the RFC’s own words, QUERY requests “can be retried or repeated when needed, for instance, after a connection failure.” Your HTTP client’s retry middleware can finally do its job on a complex read.
- Responses are cacheable. This is the part that took years to get right: the cache key “MUST incorporate the request content and related metadata” — same filter body, same cached answer.
- And one lovely affordance: the response “can include a Content-Location header field” identifying “a resource corresponding to the results of the operation” — which a client can then simply GET. Hold that thought for two sections.
One more thing, easy to miss, straight from the Security Considerations: URLs are “more likely to be logged” than request bodies. Moving query detail out of the request-target isn’t just ergonomics — every interface name, customer ID, and site code you’ve ever percent-encoded into a GET is sitting in an access log somewhere right now.
Toolchains are moving already: .NET 10 ships QUERY support, and there’s an open Rails core proposal. Browsers are earlier-stage — and for network APIs, irrelevant. This is server-to-server country.
The Sketch: A QUERY Binding for RESTCONF
First, the status line, because we’ve learned to write these plainly: as of this writing (July 20, 2026), no Internet-Draft and no NETCONF-WG thread proposes QUERY for RESTCONF. We checked the datatracker and the mail archive before publishing. What follows is a design sketch by an operator, not a spec. The point of the sketch is to show how small the thing is.
We know it’s small because RESTCONF has made this exact move before. RFC 8072 (YANG Patch) took an HTTP method the core spec didn’t use, defined a YANG-modeled media type for its payload, advertised support via a capability URN (urn:ietf:params:restconf:capability:yang-patch:1.0) in the capabilities resource, and shipped as a compact standards-track extension. No RESTCONF-bis required. A QUERY binding is YANG Patch’s little sibling — four decisions:
- Discovery. A capability URN — call it
urn:ietf:params:restconf:capability:query:1.0— inrestconf-state/capabilities. Client sees it, client may QUERY; absent, expect405 Method Not Allowed. - Request. QUERY on any data resource (
/restconf/data, or scoped to a subtree). The body isapplication/yang-data+json(or+xml) holding a smallietf-restconf-querydocument: a filter choice — NETCONF-style subtree filtering with content-match semantics, at last, or XPath where the server already advertises it — plus the existing read knobs (fields,depth,content,with-defaults) relocated as body leaves. Same semantics they’ve always had, minus the percent-encoding. (For the leaf names, steal from NMDA’s get-data — RFC 8526 already calls themsubtree-filterandxpath-filter, and so does the card below.) - Response. Exactly what GET would return for the matching data:
yang-data, ETag and Last-Modified intact, cacheable under RFC 10008’s rules. - Errors. The standard
errorscontainer; a bad filter is a400with a usableerror-app-tag, not a mystery414.
The whole thing — the wound, the fix, and the wire trace — fits on one card:
the read every NOC runs all day:
"which interfaces are down right now?"
── TODAY · RESTCONF (RFC 8040) ─────────────────
three options, all bad
1 GET the whole tree
→ megabytes of JSON to find 3 down ports
(the filter param? notification streams
only — RFC 8040 §4.8.4. datastore reads
get projection, never selection) ✗
2 target instances, one by one
GET …interface=GigabitEthernet0%2F0%2F0
?fields=interface(name%3Boper-status)…
→ percent-encoded soup vs the URL ceiling;
the real ones die as a mystery 414 ✗
3 tunnel the read through POST
→ works — and forfeits safe, idempotent,
cacheable, and "this is only a read" ✗
── THE SKETCH · QUERY (RFC 10008, June 2026) ───
QUERY /restconf/data/ietf-interfaces:interfaces
Content-Type: application/yang-data+json
{ "ietf-restconf-query:query": {
"subtree-filter": {
"interface": { "oper-status": "down" } },
"fields": "interface(name;oper-status)" } }
↑ selection, at last
1. safe + idempotent — retries are legal ✓
2. the filter rides the body: nothing
%-encoded, nothing left in access logs ✓
3. cacheable — same filter body, same
cache key, per RFC 10008 ✓
4. Content-Location: /restconf/query-results/7f3a
→ the 30 s NOC poll is conditional GETs
on THAT — 304s all shift long ✓
→ the 3 down ports. nothing else. answered
a read that can prove it's a read.
status 2026-07-20: no I-D, no WG thread yet —
operator's sketch. precedent: YANG Patch (RFC 8072)
| The read you actually want | Today | With a QUERY binding |
|---|---|---|
| ”Interfaces with oper-status down” | GET the whole tree, filter in Python | A three-line subtree filter in the body |
| Deep multi-list projection | 1,800 characters of percent-encoded fields | The same expression, readable, in JSON |
| The NOC poll every 30 seconds | A POST tunnel: uncacheable, retry-unsafe | A cacheable QUERY + conditional GETs |
And what the binding buys over the POST tunnel is precisely the metadata POST throws away:
- Retry safety by contract. Idempotence stops being a comment in your client library and becomes the method.
- Cache participation. Shared caches, conditional requests, body-in-the-key correctness — for free, per spec.
- Reads distinguishable from writes at the protocol layer. This is the quietly big one. An API gateway can mint a credential that may send GET and QUERY and nothing else — read-only enforced by generic HTTP machinery that never parses a YANG body. Anyone who has tried to build a “read-only API user” out of POST endpoints knows that isn’t a nice-to-have. It’s the whole game.
And since worked examples are how operators actually read a spec — the same binding, in the dialect you already speak:
the pipe you already type, as HTTP
(a QUERY × RESTCONF design sketch)
show ip int brief | i down
────────────────────────────────────────────
QUERY /restconf/data/ietf-interfaces:interfaces
{ "ietf-restconf-query:query": {
"subtree-filter": {
"interface": { "oper-status": "down" } },
"fields": "interface(name;oper-status)" } }
show ip bgp summary | i Idle|Active
────────────────────────────────────────────
QUERY /restconf/data/openconfig-bgp:bgp/neighbors
{ "ietf-restconf-query:query": {
"xpath-filter":
"neighbor[state/session-state != 'ESTABLISHED']" } }
show interfaces | i error
────────────────────────────────────────────
QUERY /restconf/data/ietf-interfaces:interfaces
{ "ietf-restconf-query:query": {
"xpath-filter": "interface[statistics/in-errors > 0]",
"fields": "interface(name;statistics/in-errors)" } }
(the pipe matches the WORD, even when the
count is 0 — the xpath matches the VALUE)
subtree-filter = equality, RFC 6241 §6 semantics
xpath-filter = where the server advertises it
leaf names borrowed from NMDA get-data (RFC 8526)
that ; is literal — nobody types %3B ever again
design sketch (2026-07-20) — no I-D exists. yet.
Saved Filters, Cheap Polls
RFC 10008’s Content-Location affordance maps onto network operations almost embarrassingly well. First QUERY: the server answers and adds Content-Location: /restconf/query-results/7f3a. Your dashboard then polls that URI with plain GETs — conditional GETs, even — and the filter definition lives server-side, written once.
To be very clear about lanes: this is not streaming telemetry. It isn’t on-change, it isn’t sub-second, it is not gNMI Subscribe and doesn’t want to be. But a 30-second NOC board, a nightly compliance sweep, a capacity report — the reads that today are either a full-tree GET or a bespoke POST — become boring, cacheable HTTP. In this house, “boring” is a compliment. The RFC even anticipates the failure mode: result URIs “SHOULD” avoid embedding sensitive portions of the original query.
There’s a working-group-adjacent synergy, too. The NETCONF WG’s list pagination work is in WG last call as of July 2026, and its RESTCONF binding maps the knobs onto — you guessed it — more query parameters. A query body is the natural home for pagination state the moment one exists. The WG is already investing in retrieval ergonomics; QUERY is the same instinct with better plumbing.
Deployment Economics, One More Time
In our IPv8 follow-up we scored a protocol against RFC 5218’s success criteria and watched it fail every row. Fairness demands we run this sketch through the same grinder:
| RFC 5218 asks | A QUERY binding answers |
|---|---|
| Does an early adopter gain if nobody else moves? | Yes. One server (a controller northbound) plus its own tooling captures the full benefit on day one. |
| Is deployment within one party’s control? | Largely. NSO, OpenDaylight, and the open-source YANG server stacks iterate in software-release time. No silicon, no certification matrix, no flag day. |
| Do the payers capture the value? | Completely. The team that implements it is the team drowning in percent-encoding. |
That’s the same shape gNMI’s own success took — deployer equals beneficiary, permission from no one — which is why gNMI is this post’s honest comparison and not its competition. Device firmware? Years, maybe never, and it barely matters: the software servers are where RESTCONF actually lives. If a QUERY binding ships anywhere, it ships there first, and that’s already most of the value.
The Skeptic’s Section
The case against, stated as strongly as we can make it:
- The WG has better things to do. NETCONF’s retrieval bandwidth is currently — and rightly — going into landing list pagination. An individual
-00for QUERY could sit unadopted for years. We have written recently about how that movie goes. - gNMI gravity is real. Every hour spent improving RESTCONF ergonomics competes with “just move to OpenConfig,” and for many shops the second answer is simply correct. The lane this post serves is real, but it is narrow, and it will not widen.
- Intermediaries have to learn QUERY. The caching story needs caches that implement RFC 10008’s key rules; in mid-2026 that’s servers-first, proxies trailing. Degradation is at least graceful — at worst, QUERY behaves like today’s POST tunnel, plus honest semantics.
- Ugly-but-working survives. Percent-encoding is a paper cut, not an outage, and paper cuts lose prioritization fights. RFC 5218 has a polite category for this: incremental benefit at incremental cost — the success profile of a slow crawl, not a wave.
- Maybe the install base isn’t worth the ink. That’s the bear case, and it’s respectable. The counter: the fix is nearly free — one YANG module, one capability URN, and filter semantics NETCONF has carried for two decades — and load-bearing ugliness with a nearly-free fix has a way of eventually shipping.
If none of that talked you out of it — good. Us neither.
If You Want This to Exist
A -00 here is roughly a week of work for someone who owns a RESTCONF server: one small YANG module, one capability URN, a pile of worked examples, and a Security Considerations section that mostly points at RFC 10008’s. The natural authors work on NSO, OpenDaylight, or the open-source YANG stacks — the code that benefits the day it merges. If that’s you and you want an operator to argue with, the sketch above is free; take all of it. We’ll test it against our percent-encoded scar tissue and write the follow-up when someone builds it.
One more thing, because it’s the real reason this RFC caught our eye. QUERY is HTTP finally making “this request only looks” a property a machine can verify — a read that can prove it’s a read. That happens to be the bet Transit is built on: an AI agent that investigates network devices through an interface structurally incapable of changing them, every proposed command gated by policy and by you. The terminal is free; the AI has a 14-day trial. We’re rooting for every protocol that makes “look, don’t touch” enforceable. This one included.
Sources: RFC 10008 — The HTTP QUERY Method (June 2026; all quoted language, caching, and Content-Location behavior as published) · RFC 8040 — RESTCONF (read query parameters §4.8; filter scoped to notification streams §4.8.4) · RFC 8072 — YANG Patch · RFC 6241 §6 — NETCONF subtree filtering · RFC 8526 — NMDA get-data (source of the subtree-filter/xpath-filter leaf names) · RFC 5789 — PATCH (2010 — the previous new HTTP method) · RFC 5218 — What Makes for a Successful Protocol? · gNMI specification (OpenConfig) · Cisco NSO RESTCONF northbound · draft-ietf-netconf-list-pagination (rev 13, in WG last call, July 2026) and its RESTCONF binding · ecosystem: .NET 10, Rails core proposal. The claim that no QUERY-for-RESTCONF draft or WG thread exists was checked against the IETF datatracker and mail archive on July 20, 2026. As always — argue with us.