The handshake is fresh in wg show, the endpoint is right, the keys never changed — and the ping still says no route to peer. You changed the tunnel subnet an hour ago. That symptom is the signature of a prefix mismatch rather than a key problem: WireGuard completed the handshake, then dropped the data because a source address no longer matches what the receiving peer will accept. There are two sensible ways to land a subnet change, and they fail in different places.

Two ways to land the change, and what each costs

Option A is renumbering in place: edit the interface address, the peer ranges, the routes and every copy of the config, then reload. Option B is building a second interface on the new prefix beside the old one, moving peers across, and removing the old interface once traffic has actually moved.

A: renumber in placeB: parallel interface
DowntimeThe reload window, per hostNone if peers are added to both
RollbackRe-apply the previous filesPoint peers back at the old interface
RiskHalf-applied change: new address, old rangesTwo live interfaces with overlapping intent
EffortSmall, if the deployment has one ownerHigher, and needs a cleanup step
FitsTwo or three peers you controlMany peers, remote sites, or no maintenance window

The half-applied state is what makes Option A dangerous, because it does not look broken. The interface comes up, the handshake succeeds, and only the data path fails. Option B costs more work but keeps a working path alive while you find every reference.

What has to move together on your end

Four things on the local host describe the same subnet, and a change to one is a change to all: the interface Address, each peer's AllowedIPs, the route the system uses for those destinations, and whatever the manager installs on your behalf. With wg-quick, the last two are generated from the config each time the interface comes up, so a stale copy silently reinstalls the old prefix.

Compare what is configured with what is live rather than trusting either one:

wg show
wg showconf wg0
ip addr show wg0
ip route get 10.90.0.5

The route lookup is the one people skip. It answers what the kernel would actually do for a destination, including a more specific route that a manager or a container runtime left behind. If it reports a different interface than the tunnel, the config is not the problem.

For a running interface, apply the edited file without tearing the tunnel down:

wg syncconf wg0 <(wg-quick strip wg0)

That updates peers and ranges in place. It does not update the interface address or the routes, because those are not WireGuard settings — so a renumbering still needs the interface re-created or the address changed with ip, and then the routing checked again.

What has to move together at the far end

This is where a subnet change usually dies. AllowedIPs is not only a routing hint; it is also the list of source addresses a peer is allowed to present. When you renumber clients and leave the server's AllowedIPs on the old prefix, the server accepts the handshake, receives the encrypted packets, and discards them because the inner source does not match any range it associates with that peer. No error is logged, and the client sees a timeout.

So update the receiving side with intent: the peer entry on the server must list the new client prefix, the server's own return route must point at the tunnel for that prefix, and any downstream network behind the server must learn the new path. Firewall policy that named the old range needs the same treatment, and so does anything doing source-based selection.

The diagnostic that separates the two failures is cheap. A recent handshake plus no data means the tunnel is up and the inner addressing disagrees. No handshake at all means you are looking at reachability or keys. Do not rotate keys for a prefix problem; it resets the one thing that was working.

Stale copies that outlive your edit

Editing a file is not the same as changing the running system, and the copies are more numerous than people expect: the unit or manager that owns the interface, a second profile with the same name in a different directory, a container with its config baked into an image, a router UI holding its own edited version, and a client app that re-imports a saved tunnel on launch. Each can restore the old prefix after your change looks complete.

Names travel too. If the numeric route works but the hostname fails, an internal DNS record or a service configuration still points at the old tunnel address. Fix the reference instead of widening every peer range, which would paper over the real problem and enlarge the source ACL at the same time.

Keep one recovery path open while you work: a second way into the host, a serial console, or a scheduled rollback of the config files. A tunnel change that locks you out of the machine you are changing is the most common way this task turns into an evening.

Choosing between the two, and verifying the cut

Pick A when you own every peer, the count is small, and a short outage is acceptable. Pick B when peers are remote hands you do not control, when a site-to-site link must stay up, or when you cannot guarantee that every copy gets updated in one pass. In that case add the new prefix to both interfaces, move peers one at a time, watch traffic on the new one, and only then remove the old interface and its routes.

Under either option, the change is done when four checks pass: the handshake is recent, the route lookup for a new-prefix destination names the tunnel, a payload of a few hundred bytes transfers in both directions, and the same holds after a restart of the host or the manager. The wg(8) manual is the reference for what AllowedIPs means in each direction, and it is worth re-reading before you widen a range to make a symptom disappear.

  • Handshake recent and no data: look at AllowedIPs on the receiver before touching keys.
  • Route lookup pointing at the wrong interface: a manager or container owns the route, not your file.
  • Numeric address fine and hostname broken: an old reference, not a routing loop.
  • Change complete only after a restart still uses the new prefix.

Аффингæй хæстæг статьялтæ