/commands/wireguard/wg-show-check-status
sudo wg show: check WireGuard status, latest handshake and transfer
- tool
- WireGuard
- versions
- wireguard-tools 1.0
- os
- linux, macos
sudo wg show prints every WireGuard interface with its public key and listening port, then each peer with its endpoint, allowed IPs, latest handshake and transfer counters. A recent latest handshake (seconds or a few minutes ago) and growing received bytes mean the tunnel works. A peer without a latest handshake line has never completed a handshake. sudo wg show wg0 limits the output to one interface.
The default view
sudo wg show
sudo wg show wg0
sudo wg # same as wg show: show is the default commandThe human-readable view has these fields (names from the wg source; the values below are placeholders):
interface: wg0
public key: <base64 public key of this host>
private key: (hidden)
listening port: 51820
peer: <base64 public key of the peer>
endpoint: 203.0.113.10:51820
allowed ips: 10.0.0.2/32
latest handshake: 1 minute, 12 seconds ago
transfer: 1.20 MiB received, 3.48 MiB sent
persistent keepalive: every 25 secondsendpoint appears only once the peer's address is known, latest handshake only after a successful handshake, transfer only after bytes were exchanged, and persistent keepalive only when it is set.
Script-friendly fields
Adding a field name after the interface prints tab-separated values instead, one peer per line:
| Command | Prints per peer |
|---|---|
| wg show wg0 latest-handshakes | Public key and the handshake time in Unix seconds (0 = never). |
| wg show wg0 transfer | Public key, bytes received, bytes sent. |
| wg show wg0 endpoints | Public key and the current IP:port, (none) if unknown. |
| wg show wg0 allowed-ips | Public key and its allowed IPs separated by spaces. |
| wg show wg0 dump | Everything: an interface line, then one line per peer with all fields. |
| wg show interfaces | Only the names of the WireGuard interfaces. |
| wg showconf wg0 | The running configuration in config-file format. |
A monitoring check can compare the handshake time with the current time:
now=$(date +%s)
sudo wg show wg0 latest-handshakes | while read -r peer ts; do
echo "$peer $(( now - ts ))s since handshake"
doneWhat the output tells you
- No
latest handshake: packets never got through. Check the Endpoint, the UDP port in the server firewall (for examplesudo ufw allow 51820/udp), and the public keys on both sides. - Handshake present but no traffic through the tunnel: usually AllowedIPs or routing. The source address of the packets must be inside the peer's allowed IPs.
- Handshake keeps going stale behind NAT: set PersistentKeepalive on the side behind NAT.
Unable to access interface: No such device: the interface is not up; start it withsudo wg-quick up wg0.
WireGuard has no "connected" state. It exchanges a new handshake every few minutes while traffic flows and stays silent otherwise, so latest handshake together with the transfer counters is the closest thing to a connection status.
FAQ
Why is there no latest handshake line for my peer?
wg show prints the line only after a handshake has completed. No line means the peers never reached each other: check the Endpoint address and port, that the server's UDP port is open in its firewall, and that each side has the other's correct public key.
Does wg show need root?
Yes on Linux, reading the interface needs CAP_NET_ADMIN, so run it with sudo. Without it the command fails with an Unable to access interface error that ends in Operation not permitted.
The handshake is several minutes old. Is the tunnel down?
Not necessarily. WireGuard is quiet when idle and only renews the handshake when traffic is sent. Send some traffic (ping the peer's tunnel address) and run wg show again; the handshake time should reset.