DEV Community

Rasika Dangamuwa
Rasika Dangamuwa

Posted on

Why WireGuard Connections Silently Fail: 5 Production Traps and How to Fix Them

WireGuard is one of the cleanest network protocols in modern infrastructure: under 4,000 lines of kernel code, state-of-the-art cryptography (Noise protocol, Curve25519, ChaCha20-Poly1305), and exceptional throughput.

Yet when a WireGuard tunnel breaks, debugging it can be tricky. By design, WireGuard is completely silent: it does not respond to unauthenticated packets and emits no ICMP error messages. If your configuration has a subtle mismatch, wg-quick up happily exits with code 0, the interface shows UP, and yet no traffic flows.

Here are the five most common traps that cause WireGuard connections to silently fail, along with how to diagnose and fix each.


1. The AllowedIPs Duality Trap

In standard Linux networking, routing tables and firewall rules are separate. In WireGuard, they are merged into Cryptokey Routing via AllowedIPs. This parameter serves two distinct purposes:

  • On the client: AllowedIPs defines which destination subnets get routed into the wg0 interface. 0.0.0.0/0, ::/0 routes everything (full tunnel), while 10.8.0.0/24 creates a split tunnel.
  • On the server: AllowedIPs acts as a strict source-address whitelist. If incoming traffic arrives from a authenticated peer, but its source IP is not in that peer's AllowedIPs list, the kernel drops the packet immediately.
# Server /etc/wireguard/wg0.conf
[Peer]
PublicKey = ClientPublicKeyHere=
# If client sends packets with source 10.8.0.5, this /32 will DROP them:
AllowedIPs = 10.8.0.2/32
Enter fullscreen mode Exit fullscreen mode

Fix: Ensure the server-side AllowedIPs for each peer explicitly matches the exact client address or subnet.


2. The MTU Black Hole (Ping Works, HTTPS Hangs)

A classic symptom: you can ping remote internal hosts and run small DNS queries, but opening an HTTPS page or cloning a repository hangs indefinitely.

WireGuard adds 60 bytes of protocol overhead for IPv4 (20-byte IP header + 8-byte UDP header + 32-byte WireGuard header) or 80 bytes for IPv6. If your physical network interface has standard MTU 1500 and WireGuard transmits a 1500-byte frame, intermediate routers drop the packet when Path MTU Discovery (PMTUD) is blocked by intermediate firewalls.

Diagnostic:
Test maximum non-fragmented packet size:

ping -M do -s 1392 10.8.0.1
Enter fullscreen mode Exit fullscreen mode

Fix: Set MTU = 1420 (or 1280 on PPPoE and mobile networks) in both client and server interface blocks:

[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = ServerPrivateKeyHere=
MTU = 1420
Enter fullscreen mode Exit fullscreen mode

3. NAT State Eviction Without PersistentKeepalive

WireGuard is connectionless. When idle, neither endpoint sends data.

If a client is behind a stateful NAT firewall (home router, corporate gateway, or cloud NAT), the router evicts the UDP mapping after 30–60 seconds of silence. Subsequent incoming packets from the server cannot reach the client.

Fix: Add PersistentKeepalive = 25 to the client's [Peer] section to send a 32-byte heartbeat every 25 seconds:

[Peer]
PublicKey = ServerPublicKeyHere=
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
Enter fullscreen mode Exit fullscreen mode

4. Keypair Mismatches and Asymmetric Pre-shared Keys

Because Curve25519 keys are base64-encoded strings of identical length (44 characters), a copy-paste error between server and client keys produces no error message—only an empty latest handshake in wg show.

When configuring multiple peer devices, using an in-browser builder like Nutilz WireGuard Config Generator eliminates key confusion by generating mathematically verified X25519 keypairs, symmetric PSKs, and mobile QR codes entirely client-side via WebCrypto.


5. Missing IP Forwarding and NAT Masquerade

If the client completes a handshake (latest handshake updates) but cannot reach the internet, the host kernel is dropping routed packets.

Fix:

  1. Enable packet forwarding:
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.d/99-wireguard.conf
sudo sysctl -p /etc/sysctl.d/99-wireguard.conf
Enter fullscreen mode Exit fullscreen mode
  1. Add masquerading rules to your server config:
[Interface]
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
Enter fullscreen mode Exit fullscreen mode

Summary Checklist

Symptom Primary Cause Diagnostic Command
No handshake Blocked UDP port or mismatched key sudo wg show
Ping works, HTTPS hangs MTU exceeds path capacity ping -M do -s 1392 <ip>
Tunnel drops after idle NAT mapping timeout Set PersistentKeepalive = 25
Handshake up, no internet Missing kernel IP forward cat /proc/sys/net/ipv4/ip_forward

For generating clean server/peer configurations and mobile QR codes on the fly, try the Nutilz WireGuard Config Generator.

Top comments (0)