Introduction
WireGuard has become the VPN protocol of choice for many administrators due to its simplicity, performance, and cryptographic soundness. However, when connections fail or performance degrades, effective troubleshooting requires a solid approach to log analysis. This article provides a deep, practical guide to diagnosing WireGuard issues by interpreting logs, combining systemd, kernel, and WireGuard-specific outputs, and correlating them with network-level traces. The target audience is webmasters, enterprise operators, and developers who need reliable, repeatable troubleshooting workflows.
Fundamentals: What WireGuard Logs and Where They Come From
WireGuard itself is intentionally minimal and does not produce verbose logs by default. Instead, relevant information is scattered across several sources:
- Kernel logs: WireGuard runs in kernel space; significant events (e.g., peer handshakes, dropped packets due to MTU) appear in the kernel ring buffer and systemd journal.
- systemd journal: If you use wg-quick or systemd unit files like wg-quick@wg0.service, unit start/stop messages and errors will appear in journalctl.
- wg command output: The userland tool wg and wg show report current peer states (latest handshake, transfer counters, endpoint addresses).
- Network packet captures: Tools like tcpdump or tshark show raw UDP traffic and help diagnose MTU/MSS and IP routing problems.
Basic Log Sources and Commands
Start by collecting the essential outputs. Run these on the host where WireGuard interface is configured:
- Interface state: wg show or wg show all dump.
- Kernel messages: dmesg –ctime | tail -n 200 or journalctl -k -b.
- Service logs: journalctl -u wg-quick@wg0 -b (replace wg0 with your interface).
- System logs: journalctl -b | grep wireguard or journalctl -b | grep wg-quick.
- Packet captures: tcpdump -i eth0 udp and port 51820 -w wg.pcap to capture WireGuard packets (adjust interface and port).
Collecting these outputs before making changes allows you to compare baseline vs. post-change behavior.
Interpreting wg show Output
The wg show output is the first place to look for peer health. Key fields include:
- public key – identifies the peer.
- endpoint – IP:port where the peer was last seen. If absent, WireGuard hasn’t received a packet from that peer.
- allowed ips – routing decisions are based on this; misconfiguration here is a common source of failures.
- latest handshake – timestamp of the last successful handshake. A recent timestamp indicates connectivity; stale or missing handshakes indicate a problem.
- transfer – bytes received/sent; zero values can indicate blocked traffic or no sessions.
Example diagnosis: If endpoint is missing and latest handshake is empty, the peer never initiated or the UDP path is blocked. If the handshake is recent but transfers are zero, authentication works but routing/forwarding may be wrong.
Common wg show Patterns
- Recent handshake, increasing transfer counters: healthy connection.
- No endpoint and no handshake: NAT/firewall blocking, endpoint misconfiguration, or daemon not running on the remote host.
- Endpoint present but transfer counters stagnant: path may be one-way blocked (e.g., outbound NAT allowed but inbound reply blocked), or MTU fragment issues.
Using journalctl and dmesg for WireGuard-Specific Clues
System logs integrate kernel-level messages. Look for these patterns:
- Handshake errors: kernel or wg-quick may log authentication failures when keys disagree.
- IP routing issues: messages about unable to forward packets or invalid routes point to iptables or system routing problems.
- MTU or fragment warnings: fragmentation can cause UDP packets to be dropped before WireGuard decrypts them.
Examples of useful commands:
- journalctl -u wg-quick@wg0 -b — captures unit lifecycle and configuration parsing errors.
- journalctl -k | grep wireguard — shows kernel-level WireGuard messages.
- dmesg | grep wg — rapid snapshot from the kernel ring buffer.
Network-Level Troubleshooting: tcpdump and Packet Tracing
WireGuard uses UDP; packet captures reveal whether packets reach the host and their sizes. Key checks:
- Are UDP packets arriving at the expected port? If not, the ISP/NAT may block or misroute the traffic.
- Is the source IP correct? NAT traversal may change the source; ensure that the peer endpoint matches the observed source if you hardcode endpoints.
- What are the packet sizes? Large packets that exceed the path MTU will be dropped if DF (Don’t Fragment) is set, causing silent failures. WireGuard encapsulates IP payloads, so measure UDP payload sizes.
Typical tcpdump invocation: tcpdump -n -i eth0 udp port 51820. Look for incoming packets and check UDP payload length fields. If you see incoming packets but no handshake response, userland or kernel may be blocking outbound responses (e.g., egress firewall).
MTU, Fragmentation, and Performance Issues
WireGuard adds a small header to encapsulated packets. When combined with large application packets, this can cause fragmentation and packet loss. Symptoms include intermittent connectivity, long stalls, or consistently poor throughput.
Troubleshooting steps:
- Check interface MTU: ip link show dev wg0. If MTU is default (e.g., 1420 or 1422 depending on overhead), ensure it’s tuned for your path.
- Use ping with the don’t-fragment flag: ping -M do -s <size> <peer> to discover path MTU.
- Adjust MTU on wg interface or set MSS clamping in iptables for TCP flows to avoid fragmentation.
Routing and Allowed IPs Misconfigurations
Many connectivity issues arise from incorrect AllowedIPs on either peer. This field serves both as a routing table and a policy for which peer should receive specific traffic.
Troubleshooting checklist:
- Verify that AllowedIPs on each peer include the correct remote subnets. For full-tunnel clients, this is typically 0.0.0.0/0, ::/0.
- Avoid overlapping AllowedIPs between multiple peers that create ambiguous routing.
- On Linux, check ip rule and ip route. wg-quick may add routes that override expected system defaults.
Firewall and NAT Considerations
WireGuard traffic must be allowed through the host firewall for both the UDP port and IP forwarding. Common pitfalls:
- FORWARD chain or sysctl net.ipv4.ip_forward disabled: check sysctl net.ipv4.ip_forward and iptables -L FORWARD.
- NAT rules missing for routed clients: ensure MASQUERADE or SNAT is in place for outbound traffic from VPN clients.
- Stateful firewalls: some setups drop ephemeral UDP replies; allow both directions or use conntrack helpers.
Analyzing Handshake Failures
Handshake failures are often due to incorrect keys, stale endpoints, or blocked UDP traffic. Use this systematic approach:
- Verify keys: ensure each peer’s public key is correctly set on the other peer and private keys are present locally.
- Check time skew: although WireGuard doesn’t require strict NTP, extreme time differences can complicate troubleshooting; ensure clocks are reasonably synchronized.
- Observe repeated handshake attempts in packet captures: constant retries suggest UDP is able to cross but replies are not reaching (NAT timeout, asymmetric NAT).
- When endpoints change behind NAT, consider using PersistentKeepalive on the client to maintain NAT mapping.
Advanced: Correlating Logs with conntrack and iptables
For complex NAT or multi-homed servers, correlate WireGuard logs with conntrack entries and iptables rules:
- List conntrack entries: conntrack -L | grep <peer-ip>. Look for UDP associations and expiry times.
- Check NAT translation: ensure SNAT/MASQUERADE rules are applied to the outgoing interface chosen for the traffic.
- Monitor real-time conntrack: conntrack -E shows connection events and can reveal why replies are not matched to the expected flow.
Reproducible Troubleshooting Workflow
To diagnose problems reliably, follow a reproducible workflow:
- Collect baseline: wg show, journalctl, dmesg, ip route, iptables, tcpdump snippet.
- Make one change at a time: e.g., adjust MTU, change AllowedIPs, toggle firewall rule.
- Re-collect logs and captures immediately after the change to isolate impact.
- Use timestamps to correlate events across logs: a handshake timestamp in wg show should match packet timestamps in tcpdump and kernel messages.
Real-World Example: No Traffic Despite Recent Handshake
Scenario: wg show shows a recent handshake and endpoint, but application traffic fails.
Diagnosis steps:
- Confirm transfer counters in wg show are not increasing. If they are, WireGuard is passing packets.
- Run tcpdump on both wg interface and the physical outbound interface. If packets leave wg0 but never appear on eth0, netfilter output rules or routing might be dropping traffic.
- Inspect iptables FORWARD/OUTPUT chains for DROP rules. Add logging rules using -j LOG to capture dropped packets for analysis.
- If packets appear on eth0 but responses never reach wg0, check ISP NAT, upstream firewall, or static route misconfiguration on the peer.
Conclusion and Best Practices
WireGuard troubleshooting with log analysis is about gathering the right evidence and correlating kernel-level messages, wireguard status, systemd logs, and packet captures. Key best practices:
- Always collect baseline logs before changes.
- Use wg show to verify handshakes and transfer counters first.
- Use packet captures to confirm whether UDP packets reach the host and whether replies are sent.
- Pay attention to MTU, AllowedIPs, and firewall/NAT rules—these are the most common root causes.
- Maintain scripted checks and monitoring for critical deployments to detect regressions early.
For further resources and tools tailored to managed VPN deployments and dedicated IP setups, visit Dedicated-IP-VPN at https://dedicated-ip-vpn.com/.