## TL;DR
Verify the peer's public key matches what the server expects and that UDP reaches the endpoint (test with a port check). Then check endpoint security software is not blocking WireGuard's UDP traffic. Handshake failures are key mismatch, unreachable endpoint, or blocked UDP, in that order.

## The error
```text
Handshake did not complete after 5 seconds, retrying.
```

## Steps
1. Compare the client's public key with the server's peer config. Expected: match. A reinstalled client generates a new key pair; the server still has the old public key.
2. Check the endpoint address and port in the client config. Expected: correct and current. Servers move; stale configs are common.
3. Test UDP reachability: from the laptop, check the endpoint port is reachable (no TCP fallback exists for WireGuard). Expected: reachable. Corporate egress firewalls sometimes block non-standard UDP ports.
4. Check endpoint protection: some EDR/host firewalls block WireGuard. Expected: allowed. Add an exception for the WireGuard app and its UDP port.
5. Check the system time; WireGuard rejects handshakes with large clock skew. Expected: correct time. Then retry; a successful handshake shows "latest handshake: X seconds ago".

## When to use
- WireGuard stuck at handshake
- After client reinstall or server migration

## When not to use
- Tunnel up but slow (MTU or routing)
- Authentication is via a separate layer (check that layer)

## Compatibility
- WireGuard on Windows/macOS/Linux; corporate-managed devices

## Variants
### Handshake completes then drops
Different issue (keepalive or roaming); check persistent keepalive settings.
### Works on some laptops, not others
Compare configs line by line; the difference is usually the key or the endpoint.

## Why it happens
WireGuard's handshake is a cryptographic exchange over UDP with no fallback. Any mismatch in keys, any block on UDP, or any wrong endpoint address produces the same silent retry loop.

## Edge cases
- Key rotation: coordinate client and server updates; mismatched rotation windows cause exactly this.
- MDM-pushed configs can be overwritten by user edits; redeploy the profile to reset.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_ROrmDqtgjwCZ5t5uxNX4CQ
