VyOSV · Configuration ModelConfigure mode
save / discard / exit — exiting configure mode with intent
What you'll learn
- Distinguish `save`, `discard`, and `exit` and what each does to the candidate, running, and saved configurations
- Use the safe pattern `commit; save; exit` for every change
- Recognise the failure modes where a wrong exit produces a post-reboot surprise
Prerequisites
Verified against VyOS 1.5.x LTS (circinus) · VyOS 1.4.x (sagitta) — legacy · FRRouting 10.x (VyOS 1.5) · Linux kernel 6.6 LTS (VyOS 1.5 base) · strongSwan 5.9.x (IPsec) · WireGuard 1.0.x (kernel module + userspace tooling) · 2026-08-15
save / discard / exit — exiting configure mode with intent
Three commands exit configure mode and each has a different effect on the candidate, the running configuration, and the saved configuration. Mixing them up is the source of every “where did my change go” post on the VyOS mailing list. This lesson is short but important.
The three exits
stateDiagram-v2
state Candidate {
[*] --> Editing: configure
Editing --> Editing: set / delete
Editing --> Applied: commit
Applied --> Applied: set / delete
Applied --> Empty: discard
}
state Active {
[*] --> Live: boot
Live --> Live: commit
Live --> NewLive: reboot with new save
}
state Saved {
[*] --> Disk: install image
Disk --> Disk: save
}
Editing --> Operational: exit
Applied --> Operational: exit (candidate survives)
Empty --> Operational: exit discard
Disk --> Disk: save
commit; save; exit — the safe pattern
[edit]
vyos@vyos# set interfaces ethernet eth0 address '192.0.2.1/24'
[edit]
vyos@vyos# commit
[edit]
vyos@vyos# save
Saving configuration to '/config/config.boot'...
Done
[edit]
vyos@vyos# exit
exit
vyos@vyos:~$
This is the standard exit pattern for every change. After this sequence:
- The candidate is empty (the committed change is the running config).
- The running configuration has the new address.
- The saved configuration has the new address.
- A reboot preserves the new address.
exit without save
[edit]
vyos@vyos# commit
[edit]
vyos@vyos# exit
exit
vyos@vyos:~$
After this sequence:
- The candidate is empty.
- The running configuration has the new address.
- The saved configuration has the old address.
- A reboot reverts the change.
exit discard — throw away the candidate
[edit]
vyos@vyos# set interfaces ethernet eth0 address '192.0.2.5/24'
[edit]
vyos@vyos# exit discard
exit
vyos@vyos:~$
After this sequence:
- The candidate is empty.
- The running configuration is unchanged (the
setwas never committed). - The saved configuration is unchanged.
exit discard is the right exit when the operator realises the
candidate is wrong and wants to start fresh from the running
configuration.
exit with a candidate that survives the next session
[edit]
vyos@vyos# set interfaces ethernet eth0 address '192.0.2.5/24'
[edit]
vyos@vyos# exit
exit
vyos@vyos:~$
vyos@vyos:~$ configure
[edit]
vyos@vyos# show interfaces ethernet eth0
+ address 192.0.2.5/24
The candidate survived. The next entry to configure mode shows the candidate exactly as it was left. The operator can resume editing, commit, or discard.
This behaviour is convenient for an operator who builds a change in pieces; it is dangerous for an operator who exits and assumes the candidate was discarded.
When to use each
| Scenario | Exit pattern |
|---|---|
| Change is complete and tested | commit; save; exit |
| Change is partial, more to do | exit (candidate survives) |
| Change is wrong, start over | discard; exit |
| Change is committed but should not persist | commit; exit (will revert on reboot) |
| Investigating without intent to change | exit (no edits made) |
How the result is validated
diff /config/config.boot <(show configuration commands)
ls -la /config/config.boot
ls -la /config/archive/ | tail -3
The first command confirms the saved and running configurations match; the second shows the modification timestamp; the third shows the recent archive snapshots.
How it fails
The production failure modes the engineer must recognise:
commitwithoutsave. Change works until the next reboot.savewithoutcommit.savewithout an argument writes the running configuration to/config/config.boot. If the candidate has uncommitted changes, the saved file does not contain them. The operator saves and assumes the change is persisted; it is not.discardaftercommit.discardwipes the candidate but does not undo a commit. The running configuration keeps the change; only the in-memory candidate is cleared.- Exit during a long-running script.
exitreturns to the operational shell; the script keeps running. The operator may see output arrive after the prompt has returned. - Accidental
exitinstead ofedit.exitandeditare both valid;edit <path>moves into a node,exitleaves the shell. A typo ofexitforeditdrops the operator out of configure mode.
Rollback
The exit commands are not destructive to the running configuration. The rollback path is for the underlying change, not the exit:
- Bad change in candidate:
discardorload <archive>. - Bad change in running:
commitwith aloadfrom the previous archive. - Bad change in saved: reboot from rescue ISO, edit
/config/config.bootdirectly.
Production discipline
Cross-course references
The Linux course’s V-Linux-NetConfig covers the underlying
configuration management. The Ansible course’s
XLII-Ansible-BeyondLinux covers the equivalent exit patterns
when driving the box from automation.
Quiz
Knowledge check · 4 questions
Q1. Which command sequence applies a change to the running configuration AND persists it across reboot?
Q2. Exiting configure mode with `exit` keeps the candidate in memory.
Q3. An operator commits a change and types `exit` (forgetting `save`). The change works perfectly until a power blip reboots the box. The change is gone. What should have been done differently?
The operator intended to persist the change but skipped `save`. The reboot loaded the previous `/config/config.boot`.
Q4. An operator edits the candidate, types `discard; exit`, then re-enters configure mode expecting the change to be live. It is not. What is the most likely cause?
The operator thought `discard` would undo a previous commit. It does not — `discard` only clears the in-memory candidate, not the running configuration.
Passing score: 75%. Answers are checked in this browser.