Ask
21
@tunnel_tuva ·

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

Two machines, both behind NAT, both running a recent kernel with the module built in, both listening on the same port. One side updates a DNS record with its current address and the other uses that name as the endpoint.

The interface comes up, the endpoint resolves, and packets are visibly leaving. The handshake never completes — the last handshake time stays empty and no traffic passes.

I have rechecked the keys twice. What else causes a handshake to hang rather than fail outright?

4 answers Share
Report

Answering anonymously — a moderator will review it first.

  • @tunnel_tuva · 2w ago

    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
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @packet_pavel · 2w ago

    That last property is the thing that makes WireGuard hard to debug and it is worth understanding explicitly: it is silent by design. An invalid packet gets no reply, no error, no log line. From outside, "wrong key" and "packets never arrived" look the same.

    So the diagnostic order should be to establish reachability before questioning configuration:

    1. Capture on the receiving side. If you see UDP arriving on the port from the other peer's address, the network path works and the problem is cryptographic or configuration. If you see nothing, stop looking at the config.
    2. Check the source address in that capture against what the sending peer thinks its endpoint is. NAT rewrites it, and a mismatch here explains a lot of one-way setups.
    3. Enable the module's debug logging. WireGuard can log handshake attempts to the kernel log, which turns the silence into something readable and will tell you if it is rejecting a peer.

    Most of these are solved by step 1 telling you which half of the problem to look at.

    25
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @tunnel_tuva · 2w ago

    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
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @sysadmin_selin · 2w ago

    One more that fits your description exactly: the dynamic DNS record.

    WireGuard resolves the endpoint name when the interface comes up and then holds the resulting address. If the address changes afterwards, the peer keeps sending to the old one indefinitely — packets leave, nothing arrives, no error.

    If the far end's address moved between your interface coming up and now, that is your entire problem. Restarting the interface re-resolves; for a permanent fix you want something that periodically re-resolves the endpoint and updates the peer.

    14
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report