Ask

WireGuard peers see each other's packets but the handshake never completes

Two suspects account for the overwhelming majority of these, and they present identically.

Both ends behind NAT with no port forwarding. WireGuard has no concept of a client and a server — but NAT does. If neither side has an inbound path, neither can initiate, and each is waiting for the other. The side with a forwarded port or a public address must exist; if neither has one, no amount of correct configuration will help.

The usual fix is PersistentKeepalive = 25 on the side behind NAT, which punches and maintains a mapping outward. If both sides are behind restrictive NAT, you need one of them to have a real inbound path, or a relay in the middle.

A key that is subtly wrong. You have checked twice, but the specific mistake is easy to miss: each peer's configuration must contain the other peer's public key, and its own private key. Putting your own public key in the peer section produces exactly this silent hang, because the packet is undecryptable and WireGuard's design is to not respond at all to anything it cannot authenticate.

27 · in/home-server ·

WireGuard peers see each other's packets but the handshake never completes

You mentioned one side is on a DSL-type connection, which raises the third classic: MTU.

This one does not usually stop the handshake — handshake packets are small — but it does produce the very similar experience of a tunnel that comes up and then passes no useful traffic. The encapsulation overhead plus a link that is already below the standard 1500 means large packets get fragmented or dropped, small ones work, and the connection appears to hang on anything real.

If your handshake ever does complete and things still feel broken, lower the interface MTU on both ends and retest. Working downward until large transfers succeed is a crude but effective way to find the right value.

20 · in/home-server ·