VPN kill switch not working? Test it yourself
Stop the tunnel, keep probing, read what got out. A method to test a VPN kill switch, what a working one still allows, and the causes when it fails.
Key takeaways
- A working kill switch still lets three things leave the device: DHCP, local-network traffic you allowed, and the client's own reconnect traffic.
- Our Linux run passed all 19 checks; with the tunnel down, ping and TCP to an outside host were rejected at once.
- Android Always-on VPN with Block connections without VPN is the system-level switch, and it covers the case where the app itself is stopped.
- Check first: the setting, the Android Always-on pair, excluded apps, and whether your probe hit something a working block allows.
On this page (9)
- How do I test a VPN kill switch?
- What should a working kill switch still allow?
- Does a kill switch still block if the VPN app crashes?
- Does the kill switch hold when the network changes?
- Why is my kill switch not working?
- Does the kill switch work on Android when the VPN is stopped?
- Does split tunneling affect the kill switch?
- Should the kill switch be on?
- How do I test a kill switch on a router?
A kill switch that seems not to work is usually one of four things: it is off, it is the kind that needs the app running, your probe hit an app excluded on Android, or it works and lets through what it should. Test it by stopping the tunnel and probing.
Here, a kill switch means a rule that blocks traffic while the tunnel is not carrying it. This page gives you a test you can run on a laptop in five minutes, a table of what a correct block still allows, and our own dated results from a Linux run. Every kill switch has limits, and ForestVPN's kill switch page lists the ones we know about.
How do I test a VPN kill switch?
Stop the tunnel on purpose, keep sending probes, and read what gets out. What you need: the ForestVPN app, a second terminal or tab, and a public address you are happy to ping. Do not probe a bank or any site you use daily.
- Baseline. Connect and wait for the Working (connection verdict) state: the app's status that data flows both ways through the tunnel. Run your probe once and note that it is answered.
- Start a probe that keeps running. On Linux or macOS use
ping PUBLIC_ADDRESS. On Windows useping -t PUBLIC_ADDRESS. Add a second probe that makes a name lookup and a web request, so you test a name and an address. - Stop the tunnel the way a fault would. On Linux, press Disconnect in the app (the block stays while the setting is on), or kill the service process with
sudo pkill -KILL fvpn-service, which is the crash case of our run. Do not usesystemctl stop: it removes the block by design, so answers after it are not a leak. On Windows, Disconnect and stopping the service both lift the block by design; the switch covers a tunnel that drops while you are connected, and we did not measure Windows. Quitting the window never stops the tunnel. On Android, force-stop the app. - Read the probe. Replies that stop and errors that appear mean the block holds. Replies that keep coming mean traffic is leaving outside the tunnel.
- Look at what left the device. On Linux, run a capture on your physical adapter while the tunnel is down, for example
sudo tcpdump -ni wlan0 'not arp and not port 67 and not port 68'. It lists IP packets leaving the device, minus ARP and DHCP, which a working block allows. Expect a few packets to ForestVPN's own servers (see the table below); packets to anything else are the leak. - Undo it. While the block is on, nothing has internet. Reconnect, or turn the kill switch off in settings.
Read the failure type. In our Linux run, a ping from a blocked client came back as an immediate permission error, and a TCP connection came back refused, rather than waiting for a timeout. An instant error is the block answering. A long silence can be the block or a dead network, so compare with step 1.
What should a working kill switch still allow?
A working kill switch is not perfectly silent. A few packets get out because the tunnel needs them to come back. The local network gets through only when you ask for it.
| Traffic with the tunnel down | A correct block | Why |
|---|---|---|
| Ping, TCP or UDP to a public host | Blocked | This is the case the switch exists for |
| Name lookups to a resolver on your local network | Blocked, even with the local network allowed | A resolver on the LAN is a way around the tunnel's own lookups |
| Local-network hosts | Blocked by default, allowed with the app's Allow local network access option (the LAN option) | You choose whether printers and NAS boxes stay reachable |
| DHCP (the request for an address) | Allowed | Without it the device cannot join or renew on a network |
| The client's own reconnect traffic | Allowed | It must reach its own servers to bring the tunnel back |
| Local container bridges | Allowed | They never leave the machine, so they are not among the three things that leave it |
| IPv6 | Blocked, or carried inside the tunnel | An IPv6 path outside the tunnel is the same hole as IPv4 |
Two rows trip people up. The first is the client's own traffic: a capture on the physical adapter shows a few packets to ForestVPN's servers while the tunnel is down. That is the tunnel endpoint being retried, not your browsing. The second is the local network: with the LAN option on, a ping to your router answers, and that is correct. If you want nothing on the local network reachable either, leave the option off.
A probe to a public address that gets an answer is a real failure. A packet to the client's own servers, or to your router with the LAN option on, is a pass you misread.
Does a kill switch still block if the VPN app crashes?
In our run on 2026-10-29, the Linux backend passed all 19 checks of its kill-switch scenario with no failures, and 2 checks were skipped for a reason we list below.
How this was tested
- Product
- ForestVPN Linux desktop client, shipped kill-switch backend
- Version
- source tree at origin/main on the run date; no release number typed
- System
- Linux network namespaces (client, ISP, exit and a local network as separate namespaces) inside one home-lab VM
- Checked
- Runs
- 1
Not tested
One run of the desktop kill-switch scenario on 2026-10-29, on the home lab's default line, started 05:49 UTC. The client, the ISP router, the exit and the local network are separate Linux network namespaces in one throwaway VM, which the task destroyed afterwards. Each check sends a probe from the client and records whether it was answered or rejected.
No ForestVPN production identity, account, device id, server or resolver address was used or saved; the exit is a namespace in the VM. Windows keeps its block through a drop, not after you disconnect; not measured here. Not tested: Android, Windows, macOS, iPhone and iPad, any router, or any other vendor's kill switch.
Two checks were skipped. They cover a virtual machine bridged across the host's LAN bridge, which needs the bridge-netfilter module, and it was not loaded in this VM. This is one run, one Linux build, one day.
- 19checks run
- 128passing lines
- 0failures
- 2skipped, module not loaded
Probe by probe
| Situation | Probe | Outcome |
|---|---|---|
| Switch on, no tunnel | Ping to an outside host | Rejected at once |
| Switch on, no tunnel | TCP to an outside host | Rejected at once |
| Switch on, no tunnel | TCP to a local-network host, LAN option off | Rejected |
| Switch on, no tunnel | DHCP request | Allowed |
| Switch on, no tunnel | The client's own reconnect connection (root only) | Left on the physical adapter by design |
| Switch on, no tunnel | The same connection from an unprivileged process | Rejected |
| Tunnel up | Lookups, encrypted lookups and local name-discovery traffic to the local network's resolver | Rejected |
| Tunnel up | Capture on the physical adapter | Only the tunnel's own carrier traffic |
| LAN option on | Local-network host | Reachable |
| LAN option on | Lookups to the local network's resolver | Still rejected |
| After the client crashed | Probe to an outside host | Still rejected, the table stayed |
| Firewall rules flushed by hand | Probe afterwards | Rules restored, probe rejected again |
| Switch off | Probe to an outside host | Traffic flows again |
What the crash and flush rows mean
The row that matters most for this article is the crash. After we killed the client process, the block was still in place and traffic was still refused, which is the property people mean by "fail closed". Another row is worth reading twice: when we flushed the entire firewall ruleset by hand, the client put its rules back and the next probe was rejected again.
Does the kill switch hold when the network changes?
In our run, yes: across a change of network no rule changed, and the tunnel kept passing traffic. Ranges excluded from the tunnel left on the physical adapter with the switch off and were rejected with it on, and an attempt to exclude the whole address space was refused.
Two IPv6 checks also passed. With the tunnel down, the tunnel's own IPv6 addresses did not leave the physical adapter. With the Block IPv6 toggle on in Settings, IPv6 to an outside host was rejected and nothing reached the physical adapter. We found no leak in this run, and the run says nothing about other platforms.
Why is my kill switch not working?
Work down this list from the top. Each row has a check and a fix, and the first two rows explain most reports.
| Cause | How to check | Fix |
|---|---|---|
| The setting is off | Open the app's settings; it is a setting you choose on each device | Turn it on, then rerun the test |
| I disconnected or stopped the service and traffic flowed | Note how you stopped it | Expected on Windows, and after a Linux service stop: both lift the block by design. Test with a Linux Disconnect or a killed process instead |
| Android: the app was stopped and only the in-app block was on | Stop the app and probe; traffic flows | Set ForestVPN as Always-on VPN and switch on Block connections without VPN |
| Another VPN app holds Always-on on Android | Look at Android's VPN settings for the always-on app | Pick ForestVPN there and reconnect |
| Android: your probe app is excluded from the tunnel | Check the excluded-app list | Probe from an app you did not exclude. On Windows and Linux an excluded range is blocked with the switch on, so a leak there is a real failure |
| You probed what a correct block allows | Compare the target with the table above | Probe a public address instead |
| A rule was removed by an update or another program | On the Linux firewall (nftables/netfilter) the rules live in a table; run sudo nft list tables and look for a table named fvpn | Reconnect so the client reinstalls it; reboot if the table is still missing |
| A system service goes around the tunnel (iPhone, iPad, Mac, Apple TV) | A browser probe is blocked but a system service still talks | This is a known limit; the system decides what an app can capture |
| The router, not the device, forwards the traffic | Test from a device behind the router | Use the router recipes below |
A missing table is bad news. In our run, the kill-switch table appeared when we turned the switch on and disappeared when we turned it off, so a table that is absent while the setting is on tells you the block is not installed.
If you are left with no network on Linux, the Windows and Linux installer prompts page points to a recovery section on the Linux download page. It says how to stop the service and clear the firewall tables. If you are stuck offline, sudo fvpnctl set kill-switch off turns the block off.
Does the kill switch work on Android when the VPN is stopped?
Only if you set Android's own Always-on VPN with Block connections without VPN. ForestVPN's in-app block is enforced by Android while ForestVPN is running, and the system switch covers the gap when the app is not.
Android's documentation for VPN developers describes Always-on VPN together with blocking connections that do not use the VPN. The person using the device can require all traffic to go through the VPN, and the system then blocks the rest.
The switch is in Android's settings, under the VPN entry; Android's help centre describes the VPN settings screen, and the exact menu names vary by phone.
To test it, open Android's VPN settings, pick ForestVPN as the Always-on VPN, and switch on Block connections without VPN. Then force-stop the app from the app settings and probe from a browser. The probe should fail. ForestVPN's Android Always-on page covers the battery and Private DNS settings that interact with this.
We did not measure Android for this post, so there is no run table for it; that Android run is owed.
Does split tunneling affect the kill switch?
It depends on the platform. On Android, excluded apps leave outside the tunnel on purpose, so a probe from an excluded app says nothing about the block. Probe from an app you did not exclude.
Windows and Linux exclude IP ranges, and the desktop firewall has no exclusion permit. In our run, excluded ranges left only with the switch off and were rejected with it on. So a reply from an excluded range with the switch on is a real failure, not a pass. On iPhone, iPad and Mac only a local-network carve-out exists.
Should the kill switch be on?
Keep it on if you would rather lose the connection than send traffic outside the tunnel. Turn it off if a dead connection costs more than an exposed one, for example on a captive-portal sign-in page that must load before the tunnel can.
The cost is concrete: while the block holds, nothing has internet. A "my VPN broke my internet" complaint can be just the switch doing its job. If the app shows a verdict other than Working, start here:
- VPN connected but no internet
- VPN not connecting
- net.degraded, which explains the Degraded verdict
No setting makes a kill switch absolute, and ForestVPN says so itself. A rule that fails to apply, or an update or another program that removes it, can leave the block missing.
How do I test a kill switch on a router?
Test from a device behind the router, not from the router itself, with the same stop-and-probe loop. The router recipes describe the block and give a test. ForestVPN's OpenWrt kill switch page and its kill switch for MikroTik RouterOS 7 and leak check both say how to stop the program and what to expect.
The OpenWrt page is explicit that its leak suite ran in a lab and that a hardware run is still owed, so read its status line before you rely on it. For the choice between a router and an app, see VPN router vs app.
If you want the IPv6 half of this check, IPv6 leaks covers it.
Questions and answers
Why is my kill switch not working?
Most often it is off, it is the in-app kind and the app was stopped, the probe hit an app excluded on Android, or the probe hit something a working kill switch allows by design, such as the local network.
How do I test a VPN kill switch?
Wait for the Working verdict, start a ping that keeps running, stop the tunnel the right way for your platform, and watch. A rejected or silent probe means the block holds. An answer means something got out.
Should the kill switch be on?
On if you would rather lose the connection than send traffic outside the tunnel. The price is real: while it blocks, nothing has internet until you reconnect or turn the setting off.
Does the kill switch work on Android when the VPN is stopped?
The in-app block is enforced by Android while ForestVPN is running. When the app is stopped, only Android's Always-on VPN with Block connections without VPN covers the gap.
Does split tunneling affect the kill switch?
On Android, yes: an excluded app leaves outside the tunnel on purpose, so probe from an app you did not exclude. On Windows and Linux, excluded ranges leave only with the switch off and are blocked with it on, so a leak to an excluded range with the switch on is a real failure.
Can a kill switch be absolute?
No. A rule that fails to apply, or an update or program that removes it, can leave the block missing, and on Apple systems a few system services can still go around the tunnel.
Sources
- Android Developers: VPN (always-on VPN and blocked connections) (read October 29, 2026)
- Android Help: Use a virtual private network (VPN) on your Android device (read October 29, 2026)
- netfilter.org documentation (read October 29, 2026)
- network_namespaces(7) manual page (read October 29, 2026)
How this was made
Drafted with AI assistance from Android's documentation, ForestVPN's help pages and our own Linux lab run of the shipped backend on 2026-10-29, then checked by automated gates and an editor.
