You add a peer to /etc/wireguard/wg0.conf, run systemctl restart wg-quick@wg0, and the peer is gone from the file when you look again. Nothing corrupted anything. A restart is a stop followed by a start, and the stop step can write the current runtime state back over the file you just edited. The setting responsible lives in the same file you were editing, which is what makes the loop so confusing the first time you hit it.

Two states, one file, and a save at shutdown

WireGuard's runtime state and a wg-quick configuration file are related but distinct. The file is input: wg-quick reads it, creates the interface, sets addresses and routes, and configures peers. The kernel device is the live object, and low-level changes made with wg never write themselves back.

Except in one direction. When SaveConfig = true appears in the interface section, wg-quick saves the live configuration to the file as part of bringing the interface down. The wg-quick manual warns about exactly this: changes made to the file while the interface is up may be overwritten when it is removed. It is a shutdown-time save, not a background timer, so it only fires when something stops the interface.

ActionWhat it writesWhen it surprises you
wg set on a live interfaceKernel state onlyAfter reboot, when the file was never updated
wg-quick down with SaveConfigLive state into the fileRight after you edited the file
wg syncconfKernel state onlyNever; it does not touch the file
wg-quick upKernel state from the fileIf the file is stale, you get the old tunnel

Read the table as a warning about ordering. Every accidental loss in this area comes from an edit that happened before a save instead of after one.

Stop first, edit second, start last

If the file is your source of truth, make the file authoritative by construction rather than by hope. Take the interface down, confirm it is gone, then edit, then bring it back up. The rule is simply that no edit exists while a save can still run.

sudo cp -a /etc/wireguard/wg0.conf /root/wg0.conf.$(date +%F-%H%M)
sudo wg-quick down wg0
ls /sys/class/net/wg0 2>/dev/null || echo "interface is gone"
sudoedit /etc/wireguard/wg0.conf
sudo wg-quick up wg0

The backup line is not ceremony. If the tunnel is how you reach this machine, the down step can end your session, and a copy on disk plus a console or out-of-band path is the only rollback that works. Check that second line before you trust it: a stale interface name in a script that fails silently is how people edit a file that is still live.

Setting SaveConfig = false before a normal down is the other accepted route, and it has to be done in the file wg-quick actually reads. It prevents that one automatic save. It does not make a separate NetworkManager profile, a router export or a container entrypoint reload your edits, because those managers never read this file at all.

Apply peer changes without tearing the interface down

Not every edit needs an outage. Peer-level changes can be applied to a running interface by converting the file into a configuration and syncing it, which avoids the down step entirely and therefore avoids the save:

sudo wg syncconf wg0 <(sudo wg-quick strip wg0)
sudo wg show wg0 peers
sudo wg show wg0 latest-handshakes

The strip step matters. It prints the file with wg-quick-only keys removed, so addresses, DNS and routing directives do not get fed to a tool that does not understand them. The sync then applies peers and keys to the live device without recreating the interface, so existing sessions and routes survive.

Be precise about the limits. Syncing peers does not change the interface address, the routes wg-quick added, or the resolver configuration, because none of those belong to the WireGuard device. Adding a subnet to AllowedIPs and expecting the kernel to route it is the classic misreading; the route has to be added by wg-quick at up time or by you.

Check who owns the interface before you edit anything

On a desktop or a server managed by a configuration system, the file may be an output rather than an input. A NetworkManager connection, a router's generated profile or a container startup script can all own the same interface name, and in that case a flawless wg-quick sequence still edits the wrong artefact.

systemctl status wg-quick@wg0 --no-pager
nmcli connection show | grep -i wireguard
sudo wg showconf wg0 | head -n 5

The third command prints the live configuration in the same format as the file, private key included, which is useful for comparison and dangerous in a ticket. Redact it before pasting; a private key in a support thread is a permanent compromise, not a typo.

If the service unit is inactive but the interface exists, something else created it and the file is not authoritative. That single observation saves an hour of editing a file that nothing reads.

Verify the next restart, then keep a rollback

The test that actually proves the fix is a second restart, because that is the sequence that failed the first time. Confirm the peer survives it and that the live configuration still matches what is on disk:

sudo systemctl restart wg-quick@wg0
sudo wg show wg0 latest-handshakes
sudo grep -c '^\[Peer\]' /etc/wireguard/wg0.conf

Run the restart twice. A single clean pass can be luck: the first restart may consume a runtime change that had not yet been saved, so the second is the one that tells you the file and the runtime agreed at the end of the first.

Keep the backup from the start of the process until you have done the double restart, then delete it or move it out of the configuration directory. A stray wg0.conf.bak next to the real file is harmless to wg-quick and confusing to the next person, who will eventually edit the wrong one.

ተዛመድቲ ጽሑፋት