What I Learned Trying to Teach NETCONF and gNMI

A few years ago I started to include module on model-driven network management in my graduate course. I had a sufficient background in network automation and knew about what NETCONF, gNMI, and YANG were, and why they mattered. What I did not have was the hands-on experience that comes from actually using these tools with multiple vendors’ devices and making things work from first principles.

So I had to learn all of that properly before I could teach more than just the theory. This post is about what that process looked like, what surprised me, and what eventually came out of it.

The overlooked gap

The standards are good. The RFCs describes NETCONF and YANG clearly. The OpenConfig working group publishes well-maintained models. The vendors all have documentation portals.

But there is a gap between reading a protocol specification and sending a valid configuration payload to a real device, and almost nobody writes about what lives in that gap.

The reality is this: the same OpenConfig module, on two different vendor implementations, can require subtly different XML. A module can appear in a device’s capabilities advertisement and still be unusable for configuration; it may be present for operational state only, or for compatibility reasons, or because a future release will support it. A YANG tree that looks straightforward in pyang will produce payloads that a device silently rejects until you discover that it expects a namespace prefix you had no reason to anticipate.

Some of this is documented but it may be buried somewhere in vendor release notes, GitHub issues, forum threads, and the occasional blog post by someone who hit the same issue years ago. The standards sometimes do not tell you the whole story.

Why this matters

Model-driven APIs are increasingly the primary interface for modern network platforms. Learning the theory is straightforward, but learning how to make real devices accept and return valid payloads is where most engineers struggle.

How I started

My first attempt was a small lab focused on gNMI and Nokia SR Linux YANG models. I wanted to understand how gNMI paths mapped to YANG structures, how to read operational state, and how to push configuration using JSON payloads. That work lives at GitHub repository “gnmic-srlinux-yang-lab” and was useful precisely because it was narrow in scope: one vendor and one protocol.

But the more interesting problems emerged when I introduced a second vendor.

The addition of an Arista cEOS router alongside the Nokia SR Linux nodes immediately surfaced things that a single-vendor environment didn’t. Both devices support OpenConfig. Both advertise the openconfig-interfaces module. Both can be configured using the same XML payload, mostly. The differences are small enough to ignore at first, but they are hard to ignore in a teaching context.

That is when the scope of what I was doing changed from a quick reference guide to a serious account of what model-driven configuration actually looks like in a multi-vendor environment.

What the tutorial covers

The result is a 12-task, lab-based tutorial that runs on Containerlab, an open-source network emulation platform that spins up Nokia SR Linux and Arista cEOS instances on a laptop.

The tasks follow a logical sequence. You start by verifying protocol connectivity, then explore what each device actually supports through its capabilities advertisement, then learn to read YANG module trees with pyang, and then work through progressively more complex configuration: interfaces, network instances, IPv4 addressing, OSPF, and finally operational state retrieval and streaming telemetry with gNMI Subscribe.

The tutorial does not skip the interesting parts. You build every payload by hand, from the YANG tree, because that is the only way to understand why it has to look exactly the way it does.

The reference section includes a command quick reference and a guide to all the payload-building techniques encountered across the tasks.

The things that did not work

Some of the most useful content in the tutorial is about what failed.

The Arista cEOS routing table is not accessible via gNMI in the version used for this tutorial, neither through the OpenConfig AFT (Abstract Forwarding Table) model nor through native EOS paths. This is a known limitation of the OpenConfig model that supported configuration more successfully than operational state.

Similar patterns appear in other places: Nokia SR Linux uses its native OSPF module for configuration even though it also advertises the OpenConfig OSPF module, because the native module covers the full feature set while the OpenConfig module’s support is partial. cEOS uses the OpenConfig module for OSPF configuration but has no equivalent native YANG exposure for OSPF state via gNMI.

Teaching these inconsistencies honestly is, I think, more useful than pretending they do not exist. A student who has seen a real device reject a perfectly valid OpenConfig payload because the vendor’s implementation is partial is much better prepared for production work than one who has only ever used a simulator that behaves exactly as the standard specifies.

What I learned about learning this

A few observations from the process that might be useful to others attempting something similar.

The pyang sample-xml-skeleton output is a starting point, not an answer. It generates a template containing every element in the module, with no indication of which fields are mandatory, which are optional, and which the device will silently ignore or actively reject. It is most useful as a map of the territory, not as a payload you can fill in and send.

The most reliable technique for building a payload for an unfamiliar feature is to configure it via CLI first and then retrieve the configuration over NETCONF or gNMI. The device returns exactly what it stored, with correct namespaces, element names, and key values. If the goal is to automate a large network, then creating the desired configuration on a non-production device then replicate it across the production network is a sensible approach and it requires understanding the YANG structure anyway.

Revision dates matter more than most introductory material suggests. When a device advertises a module at revision 2014-05-08 and another device advertises the same module at revision 2018-02-20, those are genuinely different modules that may have different mandatory fields, different namespace structures, and different behaviour under the same operation. Treating them as interchangeable may lead to subtle bugs.

gNMI and NETCONF are complementary, not competing. NETCONF is well-suited to transactional configuration changes where you need candidate datastore semantics, validation before commit, and rollback on failure. gNMI is better suited to operational state retrieval and streaming telemetry, where its Subscribe RPC enables real-time push from the device rather than repeated polling. A complete management stack uses both.

Where this is heading

The process of building this tutorial made something else clear: the same inconsistencies that make model-driven configuration hard to learn are what make it hard to automate at scale. Every organization that manages a multi-vendor network using YANG-based APIs has to deal with the namespace differences, the revision mismatches, and the gaps in OpenConfig coverage, and they may need to deal with them by writing vendor-specific code that is fragile and hard to maintain.

That observation is pointing toward the next project. The general direction is a framework that accepts user intent at a higher level of abstraction and handles the vendor-specific translation underneath, so that the person configuring the network does not need to know whether they are talking to a Nokia device that uses a native OSPF module or an Arista device that uses OpenConfig.

More on that when it is ready.

In the meantime, the tutorial is at model-driven-configuration-tutorial. If you are trying to learn this properly, or teach it, I hope it saves you some of the time I spent.


The lab uses Nokia SR Linux 25.10.1 and Arista cEOS 4.35.1F running in Containerlab. All tools used, gnmic, pyang, netconf-console2, ncclient, are open source.