VPN failures cluster into a handful of patterns: the tunnel never establishes (handshake failure), the tunnel establishes but nothing flows (routing or MTU), some things work and some don't (split tunnel or DNS), or the tunnel works but leaks (DNS or IPv6 going around it). Each pattern has a different cause and a different fix, so the first job is figuring out which one you actually have.
This guide is defensive troubleshooting for your own VPN (corporate WireGuard, OpenVPN, IPsec, or a commercial client), not a tour of VPN products.
Step 1. Confirm the underlying internet works
Obvious, frequently skipped. Disconnect the VPN entirely and run a ping test against a public host. If the underlying connection is flaky, the VPN will be flaky, and no amount of client-side fiddling fixes that.
While you're disconnected, note your public IP with What's My IP. You'll compare against it later to confirm the tunnel is actually carrying traffic.
Step 2. Verify the VPN server is reachable
The tunnel can't establish if the endpoint is down or the port is filtered. Check both:
- Host is up. Ping the VPN server's hostname or IP. Note that many VPN endpoints deliberately drop ICMP, so a failed ping isn't conclusive, but a successful one rules out a whole category.
- Port is open. Use the Port Checker against the server on the protocol's port: WireGuard defaults to UDP 51820, OpenVPN to UDP 1194 (or TCP 443 in TCP mode), IPsec/IKEv2 needs UDP 500 and 4500.
The UDP part matters. Hotel, café, and guest networks frequently block all UDP except DNS. If the handshake fails only on certain networks, this is the prime suspect. Workarounds: switch OpenVPN to TCP 443 (slower, but it traverses almost anything), or move WireGuard to a port the network permits; some setups run it on UDP 53 or 443 for exactly this reason.
Step 3. Diagnose handshake failures
If the server is reachable but the tunnel still won't come up, read the client log; every client has one, and the handshake error is usually explicit.
- WireGuard: "Handshake did not complete after 5 seconds." Either UDP is blocked (step 2), the server isn't running, or (very commonly) the keys are wrong. Check that your public key is actually registered on the server and the server's public key in your config matches. WireGuard gives the same silent timeout for "blocked" and "wrong key," which is why you ruled out the network first.
- OpenVPN: "TLS handshake failed." Wrong CA certificate, expired client certificate, or
tls-auth/tls-cryptkey mismatch. Check certificate expiry first; client certs issued with 1-year validity expire on schedule and produce exactly this error. - IPsec: stuck in phase 1. Usually a PSK mismatch or an IKE proposal mismatch (cipher suites that don't overlap between client and server). NAT between you and the server requires NAT-T on UDP 4500; if 500 works but 4500 is blocked, phase 1 succeeds and phase 2 dies.
- Auth failures. Expired AD password, revoked certificate, or MFA token problems land here. The log line will say authentication, not TLS. Don't burn an hour on networking when the password expired yesterday.
Step 4. Tunnel up, traffic dead: check MTU
This is the classic "VPN connects fine but pages hang" failure. The tunnel's encapsulation overhead (60-80 bytes depending on protocol) means packets near the standard 1500-byte Ethernet MTU don't fit once wrapped. Small packets (ping, DNS, TCP handshakes) pass; full-size packets (actual page loads, file transfers) get dropped or need fragmentation that something in the path silently blocks.
Symptoms: ping over the tunnel works, ssh connects then freezes, HTTPS sites stall after the request is sent.
Confirm it by finding the largest unfragmented packet that survives the path:
# macOS / Linux - do-not-fragment ping, binary-search the size ping -D -s 1400 vpn-internal-host # macOS ping -M do -s 1400 vpn-internal-host # Linux
If 1400 passes and 1472 fails, set the tunnel interface MTU to the working payload size plus 28 (ICMP+IP headers). For WireGuard, MTU = 1380 in the config is a safe conservative value; OpenVPN has tun-mtu and the often-more-effective mssfix 1360, which clamps TCP MSS so endpoints never send oversized segments in the first place.
Step 5. Check for DNS leaks and DNS failures
Two opposite problems share this layer:
- DNS not working over the VPN. You can reach internal hosts by IP but not by name. The client isn't applying the VPN's DNS servers, or the internal DNS server isn't reachable through the tunnel. Check which resolver the OS is actually using (
scutil --dnson macOS,resolvectl statuson Linux) and confirm internal names resolve against the VPN-pushed resolver. - DNS leaking around the VPN. Queries go to your ISP's resolver even while tunneled, which defeats the privacy point and breaks split-horizon DNS (internal names that only resolve inside). Connect the VPN, then check What's My IP: if your public IP still shows your ISP rather than the VPN egress, the tunnel isn't carrying your web traffic at all. Also watch for IPv6 leaks: if the VPN only tunnels IPv4 and your network has native IPv6, traffic to dual-stack hosts bypasses the tunnel entirely. Either tunnel IPv6 too or disable it on the physical interface.
Step 6. Untangle split-tunnel routing
Split tunneling sends only specific subnets through the VPN. When "some things work and some don't," compare the broken destination against the routes the VPN installed:
netstat -rn # macOS ip route # Linux route print # Windows
Typical findings:
- The internal subnet you need simply isn't in the pushed routes; ask the VPN admin to add it.
- Overlapping subnets. Your home LAN is
192.168.1.0/24and so is the office network. The local route wins, and office hosts on that range are unreachable. Fix is renumbering your home LAN (once, painfully, forever) or full-tunnel mode. - Full-tunnel configured but a more-specific local route is hijacking part of the traffic.
Step 7. Stabilise a connection that keeps dropping
For tunnels that establish, work, then die:
- NAT timeout. Home routers expire idle UDP mappings, often after 30-120 seconds. WireGuard's
PersistentKeepalive = 25exists precisely for this. OpenVPN haskeepalive 10 60. - Wi-Fi roaming / sleep. Laptops switching APs or waking from sleep change source port or IP; some clients re-handshake gracefully, others need a manual reconnect. Newer clients and WireGuard handle roaming well; if yours doesn't, update it.
- Server-side idle disconnects. Corporate concentrators often drop sessions after N hours or on inactivity by policy. If drops happen at suspiciously round intervals, it's policy, not your network.
TL;DR
- VPN off: confirm the raw connection works with a ping test; note your IP via What's My IP.
- Port-check the endpoint: WireGuard UDP 51820, OpenVPN UDP 1194/TCP 443, IPsec UDP 500+4500. Guest networks blocking UDP is the top handshake cause.
- Handshake errors: read the client log; keys, expired certs, and PSK mismatches are explicit there.
- Tunnel up but stalls: it's MTU. DF-ping to find the working size, clamp the tunnel MTU or MSS.
- Name resolution broken or leaking: verify which resolver the OS uses and re-check your public IP while connected.
- Partial reachability: inspect the routing table for missing or overlapping split-tunnel routes.
- Drops on idle: keepalives (WireGuard
PersistentKeepalive = 25) defeat NAT timeouts.
Related
- Port Checker: verify the VPN port isn't filtered
- What's My IP: confirm the tunnel is your egress and spot leaks
- Ping Test: baseline the underlying connection
