NETCONF is the protocol that replaced screen-scraping. Instead of sending CLI commands and parsing the text that comes back, you exchange structured XML over an SSH session, against a formal YANG data model. The result is automation that does not break when Cisco reformats a show command, and that can distinguish configuration from operational state cleanly. It is the foundation of model-driven management, and the Python library ncclient makes it approachable.
This article walks through NETCONF on Cisco IOS XE, driven from a real Linux automation host. It extends the Network Automation cluster guide.
A Note on the Lab
Consistent with this site's rule that captured output is real, here is the honest state of this lab. The automation host (a Debian VM with ncclient, requests, and pyang installed) is real, and it reaches the target router. The target is a Catalyst 8000v with the full NETCONF/YANG stack enabled, and its device-side state is captured live below. However, on this virtual platform the DMI datastore (the confd/ndbmand backend that serves NETCONF on port 830) did not finish initializing within the lab window, a known limitation of the virtualized DMI, so the port did not come up to serve requests. The ncclient request and XML response structure shown below is therefore documentation-style, drawn from Cisco's documented NETCONF behaviour and clearly framed as such. The device configuration and the show output confirming the stack is enabled are real captures. No XML is presented as a lab capture that was not one.
What NETCONF Actually Does
NETCONF (RFC 6241) has a few defining properties that make it different from SSH-and-scrape:
It runs over SSH on port 830 (distinct from the management SSH on 22), and the operations are a small, defined set: get, get-config, edit-config, lock, unlock, commit.
Enabling It, and Confirming the Stack
On IOS XE, NETCONF is one command, plus a crypto key for the SSH transport:
R2(config)# netconf-yang
R2(config)# crypto key generate rsa modulus 3072Modern IOS XE (17.x) requires at least a 3072-bit key before it will bring up SSH, which NETCONF depends on. Once enabled, the router runs a set of background processes (the DMI, Data Model Interface) that actually serve NETCONF and RESTCONF. You can confirm they are up, and this is a real capture:
R2#show platform software yang-management process
confd : Running
nesd : Running
syncfd : Running
ncsshd : Running
dmiauthd : Running
nginx : Running
ndbmand : Running
pubd : RunningEach process has a job: ncsshd is the NETCONF SSH server (port 830), nginx serves RESTCONF (port 443), confd and ndbmand are the datastore backend, pubd handles telemetry. And the NETCONF-specific status, also real:
R2#show netconf-yang status
netconf-yang: enabled
netconf-yang ssh port: 830
netconf-yang side-effect-sync: enabled
netconf-yang ssh hostkey algorithms: rsa-sha2-256,rsa-sha2-512,ssh-rsaWhen NETCONF is not working, this is the first place to look: is the feature enabled, are the DMI processes running, and is the SSH key present. If ncsshd is not running or the datastore backend has not finished initializing, port 830 will not accept connections even though the configuration looks correct, which is exactly the failure this lab hit on a virtual platform.
The Hello Exchange
Every NETCONF session opens with a hello exchange in which both sides advertise their capabilities, the list of YANG models and features they support. This is how a client discovers what a device can do. Using ncclient:
from ncclient import manager
m = manager.connect(
host="10.0.12.2", port=830,
username="admin", password="Cisco@123",
hostkey_verify=False,
device_params={"name": "iosxe"})
print("Session id:", m.session_id)
for cap in m.server_capabilities:
if "ietf-interfaces" in cap:
print(cap)The server_capabilities list is the device telling you every model it supports. Filtering it (as above) is how you confirm a model like ietf-interfaces is available before you try to use it. The device_params={"name": "iosxe"} tells ncclient to use the IOS XE dialect, which matters for some operations.
Reading Configuration: get-config
To read an interface's configuration, you send a get-config with a filter that names the subtree you want (from the YANG model). The request and the shape of the reply:
filter = """
<filter>
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
<interface><name>GigabitEthernet2</name></interface>
</interfaces>
</filter>"""
reply = m.get_config(source="running", filter=filter)
print(reply)<!-- reply (structure per the ietf-interfaces model) -->
<data>
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
<interface>
<name>GigabitEthernet2</name>
<enabled>true</enabled>
<ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
<address><ip>10.0.12.2</ip><netmask>255.255.255.252</netmask></address>
</ipv4>
</interface>
</interfaces>
</data>Notice the filter names the exact subtree, and the reply returns exactly that subtree as structured XML. No show output, no parsing, no ambiguity. The source="running" reads the running datastore; you could equally read startup.
Changing Configuration: edit-config
Writing is edit-config: you send the XML for the new state, targeting a datastore. Changing an interface description:
config = """
<config>
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
<interface>
<name>GigabitEthernet2</name>
<description>Configured via NETCONF</description>
</interface>
</interfaces>
</config>"""
reply = m.edit_config(target="running", config=config)
# reply contains <ok/> on successOn a platform with a candidate datastore you would target candidate, then commit, giving you an atomic all-or-nothing change. IOS XE historically writes directly to running. The success indicator is an <ok/> element in the reply; an error returns an <rpc-error> with a type and message, the XML analogue of the HTTP error codes RESTCONF uses.
NETCONF or RESTCONF?
They target the same YANG models over different transports. The short guidance:
The RESTCONF article covers the HTTP side. For most quick tasks RESTCONF is easier; for transactional multi-step configuration, NETCONF's datastore model is worth the extra ceremony.
FAQ
What port does NETCONF use?
TCP 830 over SSH, separate from management SSH on 22. If 830 refuses connections, check that netconf-yang is enabled, the DMI processes (ncsshd especially) are running, and an SSH key exists.
Why is port 830 not responding even though netconf-yang is enabled?
The DMI backend (confd/ndbmand) may not have finished initializing, or the SSH key is missing. Check show platform software yang-management process and show netconf-yang status. On virtual platforms the datastore can be slow or fail to initialize.
Do I need a candidate datastore for transactions?
For true atomic commit, yes. IOS XE historically writes to running directly. Check the device's advertised capabilities in the hello exchange for candidate support.
How do I know which models a device supports?
The hello exchange. m.server_capabilities in ncclient lists every model and feature the device advertises. Filter it to confirm a model before using it.
NETCONF or RESTCONF for a simple change?
RESTCONF is simpler for a straightforward read or single edit. NETCONF is better when you need locking, a candidate datastore, or transactional multi-step changes.
Key Takeaways
- NETCONF exchanges structured XML over SSH (port 830) against YANG models, replacing fragile screen-scraping.
- It separates datastores (running/candidate/startup) and config vs operational state, enabling atomic changes on capable platforms.
- Enable with
netconf-yangplus a 3072-bit RSA key. Confirm the DMI processes withshow platform software yang-management process- this is the first troubleshooting step. - Every session opens with a hello exchange advertising capabilities;
ncclient'sserver_capabilitieslists supported models. - Core operations:
get-config(read a filtered subtree),edit-config(write structured XML), with<ok/>or<rpc-error>as the result. - Honest platform note: on this virtual cat8000v the DMI datastore did not finish initializing, so port 830 never served requests. The device state shown is real; the XML request/response structure is documentation-framed, never faked as captured.
Next: RESTCONF on Cisco IOS XE, or the Network Automation cluster guide.