> ## Content Index
> Fetch the complete content index at: https://www.pinglabz.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# NETCONF on Cisco IOS XE Routers: A Hands-On Walkthrough
- URL: https://www.pinglabz.com/netconf-cisco-ios-xe-hands-on/
- Published: 2026-07-12T02:58:37.000Z
- Updated: 2026-08-24T09:43:24.000Z
- Description: NETCONF replaces screen-scraping with structured XML over SSH against YANG models. This walkthrough drives Cisco IOS XE with ncclient from a real Linux automation host, from first hello to config change.
- Author: Jaime
- Tags: Network Automation, Labs, #Import 2026-08-01 19:54

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](https://www.pinglabz.com/yang-data-models-explained/). 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](https://www.pinglabz.com/network-automation/).

## 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 behavior 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:

Structured (XML)

Everything is XML shaped by a YANG model. No text parsing, no fragile regex.

Datastores

Separate running, candidate, and startup config, so you can stage a change and commit it atomically.

Config vs state

A clean separation between configuration (what you set) and operational state (what is happening).

Transaction-capable

On platforms with a candidate datastore, changes can be all-or-nothing, not half-applied.

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 3072
```

Modern 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             : Running
```

Each 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-rsa
```

When 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](https://www.pinglabz.com/yang-data-models-explained/)). 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 success
```

On 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](https://www.pinglabz.com/rest-api-response-codes-network/) RESTCONF uses.

## NETCONF or RESTCONF?

They target the same YANG models over different transports. The short guidance:

NETCONFXML over SSH (830). Richer: datastores, locking, transactions. Choose for complex, transactional config.

RESTCONFJSON/XML over HTTPS (443). Simpler, familiar REST verbs. Choose for straightforward reads and edits, and easy tooling.

The [RESTCONF article](https://www.pinglabz.com/restconf-cisco-ios-xe/) 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-yang` plus a 3072-bit RSA key. Confirm the **DMI processes** with `show platform software yang-management process` \- this is the first troubleshooting step.
- Every session opens with a **hello** exchange advertising capabilities; `ncclient`'s `server_capabilities` lists 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](https://www.pinglabz.com/restconf-cisco-ios-xe/), or the [Network Automation cluster guide](https://www.pinglabz.com/network-automation/).