The identity vanishes from the running interface and the change looks done. After the service restarts, it is back, which reads like WireGuard ignoring the command. What actually happened is simpler: the startup configuration still contains the peer.

Two states hold that list. Revocation is only real when both of them lose it.

What wg set Actually Changes

The command wg set wg0 peer <public-key> remove edits the running interface in the kernel. It writes nothing to disk. The configuration file, the NetworkManager profile or the router saved state is untouched. That is the design, not a bug.

That separation is deliberate, because the tool has no idea who owns the interface. A runtime command must be safe to run against an interface managed by something else. It cannot guess where the durable copy lives. The consequence is easy to state: a runtime removal is temporary by construction.

So the peer returns on the next restart, and it returns with its original allowed prefixes. Anything routed through it is recreated as well. A supposedly revoked identity can therefore reach its former destinations after a reload. Nothing in the runtime output warned anyone.

Find the Writer Before You Edit a File

The interface has an owner. It might be wg-quick reading a file, NetworkManager applying a profile, a router's own interface configuration, or a container entrypoint that recreates the interface on start. Editing a file that the owner never reads produces no persistent change at all.

Start from the running interface and identify the public keys, since names and addresses are weaker identifiers than the key itself. Then compare that list with the saved configuration the owner actually reads.

wg show wg0 peers
wg show wg0 allowed-ips
systemctl status wg-quick@wg0 --no-pager
ls -l /etc/wireguard

A live interface whose peer list and file contents disagree is the whole diagnosis. The saved configuration wins at boot, and the runtime state loses. Compare them before changing either one.

The SaveConfig Trap

wg-quick adds a wrinkle that catches people who edit files by hand. With SaveConfig enabled, its documented shutdown behaviour writes the current runtime state back over the configuration file.

That reverses the usual direction of persistence. You remove a peer from the file, then the service stops. The running state is written back over your edit, restoring the peer you just deleted.

The order therefore matters: edit the file while the interface is down, or disable SaveConfig before doing the edit, then bring the interface back up and confirm what was loaded. A hand edit made while the interface is up is a race with the shutdown write.

Change Both States, Then Reload

In the runtime, remove the peer by key. In the saved configuration, remove the same block through the owner's supported operation rather than by editing around it.

Then review what the peer carried. A routed network that belonged to the revoked identity should be reassigned deliberately or removed, not silently inherited by whichever peer is edited next.

Keep a recovery path open if the gateway also carries your administrative access. A restart that removes the wrong peer is a self-inflicted outage. The same applies to a restart that removes the wrong route.

What a Passing Test Looks Like

Reload or restart the service, then read the peer list again. The old key must be absent, and the peers you meant to keep must still be present and working.

wg show wg0 peers
wg show wg0 allowed-ips
sudo wg-quick down wg0 && sudo wg-quick up wg0
wg show wg0 peers

Where the situation allows it, confirm that the old identity no longer reaches its former resources. A tidy interface listing before a restart is half a test. The other half is what the identity can still do afterwards.

If a manager keeps restoring the peer, stop repeating the low-level removal. Fix the inventory that writer reads, because until then every restart is another invitation for the identity to reappear.

Artaigilean co-cheangailte