Kill switch on, traffic still leaked: why it happens
A kill switch blocks traffic when the tunnel is down, but it cannot block traffic before it starts running. The three real failures are the boot window before the client loads, partial coverage that misses IPv6 or local traffic, and a tunnel that is broken while still reporting connected.
4 min read
A kill switch is a firewall rule, or a set of them, that drops traffic not destined for the tunnel. That is all it is. Understanding it as a rule rather than as a guarantee explains every way it fails.
Failure one: the boot window
Rules installed by an application exist once that application is running. Between the network coming up at boot and the VPN client starting, there is a window where traffic can leave.
It is short, and it is not empty. Operating systems check for captive portals, sync clients reconnect, and update services phone home, all within the first few seconds of a network appearing.
What actually closes it:
- Android: the "block connections without VPN" setting, which is enforced by the system rather than by the app, and applies from boot.
- Linux: firewall rules installed persistently rather than by
wg-quick'sPostUp, so they survive independently of the interface. - Windows and macOS: depends on the client. A client that installs a persistent filter closes it; one that adds rules at connect time does not.
Failure two: partial coverage
A kill switch that blocks IPv4 and not IPv6 is a common implementation gap. On a dual-stack connection, that means every site with an AAAA record is reachable around the switch.
Similarly, most kill switches deliberately allow traffic to the local network, so that printers, network shares and casting keep working. That is a reasonable default and it is a hole: anything on the local network is reachable, and on a café network the local network is everyone else in the café.
Check whether your client's kill switch has a "block local network access" option and whether it covers IPv6. If it cannot say, assume it does not.
Failure three: the tunnel is not actually down
This is the one that produces the confusing reports. The client shows connected, the kill switch is engaged, and traffic is flowing outside the tunnel.
Almost always the tunnel is up at the interface level while being useless: a peer that has not completed a handshake in twenty minutes, an endpoint that has moved, or a route that was removed by something else. The kill switch is watching the interface state, and the interface state says fine.
Diagnose it by looking at the actual evidence rather than the icon:
sudo wg show # a recent handshake and rising counters, or not
On desktop clients without that, disconnecting and reconnecting forces a fresh handshake and resolves it.
Failure four: the rules did not survive
Windows and macOS clients that install firewall rules can have them removed by a system update, a firewall reset or another security product. The client's interface still shows the setting as on, because it stores its own state, but nothing is enforcing it.
Toggling the setting off and on reinstalls the rules and is worth doing after any major OS update.
How to test it properly
Do not test by disconnecting the VPN in the client, because a well-behaved client tears the tunnel down in an orderly way and the kill switch has every opportunity to engage.
Test by simulating a failure:
- Start a continuous ping to a public address, or open a page that auto-refreshes.
- Kill the VPN process rather than disconnecting it. On Linux,
pkill; on Windows, end the task in Task Manager. - Traffic should stop immediately and completely.
- Check IPv6 separately, with a ping to an IPv6 address.
If traffic continues for more than a moment, the switch is not doing what you believe.
What a kill switch cannot do
It cannot protect traffic that already left. It cannot undo a DNS lookup already answered. And it cannot cover a machine before it is running, which is why the system-level implementations are meaningfully better than the app-level ones.
It also cannot help if the VPN client itself is the thing that failed to start. On a machine where that matters, a persistent firewall rule that only permits the tunnel interface and the VPN endpoint is the arrangement that survives the client being absent entirely.
After enabling it, verify the normal case too
A kill switch that blocks correctly is easy to confuse with a network fault. Once it is on, confirm the ordinary path still works: what is my IP should show the server, and the DNS leak test should show the tunnel's resolvers. A machine that appears to have no internet after enabling a kill switch is usually working exactly as configured, with the tunnel down.