Walk me through a full NETCONF change session, from connecting to closing, including what can go wrong.
Show the answer
Say this first
SSH to port 830 and request the netconf subsystem. Both sides send hello; the server's lists its
capabilities and a session-id. I lock the candidate, send edit-config, run validate, then commit
with confirmed and a timeout. I run my checks, send a confirming commit, unlock and
close-session. Any failure comes back as an rpc-error with a type, tag, severity and message, and I
discard-changes or let the confirmed commit roll back.
Go deeper
Step by step
- Transport. SSH to TCP 830, subsystem
netconf. Authentication is normal SSH (password or key, often via AAA). - Hello. The server sends its capabilities and a
session-id; the client sends its own. If both listbase:1.1, framing switches to chunked. - Lock the candidate (and running, if the platform asks for it).
- edit-config to the candidate.
- validate the candidate (with
:validate). - commit with
<confirmed/>and<confirm-timeout>. - Check reachability and state from the automation side.
- Confirming commit (a plain
<commit/>), then unlock and close-session.
The same flow with ncclient
from ncclient import manager
CONFIG = """
<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
<interface>
<name>GigabitEthernet2</name>
<description>to SW1 Gi1/0/48</description>
</interface>
</interfaces>
</config>
"""
with manager.connect(host="10.0.0.1", port=830, username="netops",
password="secret", hostkey_verify=False) as m:
with m.locked(target="candidate"):
m.discard_changes()
m.edit_config(target="candidate", config=CONFIG)
m.validate(source="candidate")
m.commit(confirmed=True, timeout="120")
# run post-checks here; if they fail, do nothing and the device rolls back
m.commit()discard_changes() first clears anything another session left in a shared candidate.
hostkey_verify=False is for a lab; in production load known host keys.
What an error looks like
<rpc-reply message-id="102" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<rpc-error>
<error-type>protocol</error-type>
<error-tag>lock-denied</error-tag>
<error-severity>error</error-severity>
<error-info>
<session-id>31</session-id>
</error-info>
</rpc-error>
</rpc-reply>error-type is transport, rpc, protocol or application. For lock-denied, error-info names the
session holding the lock. The error-message text varies by vendor.
Common failures
- Port 830 refused: NETCONF not enabled, or an ACL on the management plane.
MissingCapabilityErrorin ncclient: you targeted the candidate on a device that does not offer it.unknown-elementorinvalid-value: wrong namespace, a typo, or a node the platform does not support.lock-denied: another session or a stuck session holds the lock;kill-sessionfrees it if you are sure.
They will ask next
What does persist do on a confirmed commit?
With
:confirmed-commit:1.1,<persist>gives the confirmed commit a token so a different session can confirm or cancel it with<persist-id>. Without it, the confirmed commit is tied to the session that started it, and closing that session rolls the change back.
Traps
- Forgetting the confirming commit. The change works for two minutes and then quietly reverts.
- Leaving a lock held by a crashed script. Use a context manager so the lock is always released.