Kill switch on, an app deliberately excluded from the tunnel, and the two requirements now contradict each other. One says nothing may leave except through the tunnel, the other says this program must go direct. Every client resolves that conflict differently, and the settings page rarely explains which rule wins. Write the policy per application before trusting any label.

Two Policies, One Machine

A kill switch is a promise about failure: when the tunnel is not protecting traffic, the traffic stops. Split tunnelling is a promise about selection: these programs or destinations use the tunnel, and those do not. The second promise creates traffic that the first has to decide about. Neither promise is wrong; they were simply written by different people for different threats.

Three outcomes are possible and only one of them is what the deployment intended. The excluded app may stay direct during an outage, which honours the split and breaks the kill switch. It may be blocked with everything else, which honours the kill switch and breaks the split. Or it may be blocked only sometimes, depending on how the platform evaluates the rule after an interface disappears. That last case is the one that generates tickets.

Write the App List Before the Rule

List the programs that must use the tunnel, the ones that must go direct, and the names or destinations that must never appear on either list. Include resolver behaviour and the IPv6 side separately, because both can follow a different policy from page traffic.

Per-app rules usually match an executable or a package, not a profile inside it. A browser profile, a private window and an extension carry no network identity of their own, so they inherit whatever the process received. A helper process launched by that browser may not inherit the same rule at all.

Two lists are needed, not one: what the tunnel must carry, and what must never travel outside it for any reason. An application that appears on both is a requirement conflict rather than an implementation detail, and it has to be settled before the client is configured.

What the Client Does During an Outage

Some implementations block excluded apps during an outage and restore their access on reconnect. Others preserve the direct path throughout, which is consistent with the split and weaker as a safety property. Platform-level lockdown can override the client's own per-app selection entirely. That difference is not cosmetic, because it decides whether the excluded app is a policy exception or a hole.

Android's always-on VPN with the block-connections-without-VPN option is the clearest case, since the platform enforces the lockdown rather than the client, and an excluded package is blocked with everything else while the tunnel is down. A desktop client that applies per-app exclusions inside its own driver usually leaves the excluded process on the physical interface, because it never owned that process's traffic to begin with. Both behaviours are defensible, and only one of them matches a requirement that says the excluded app must stay usable. Ask which component enforces the rule before you interpret the result.

Read the behaviour for the operating system in front of you rather than the setting with the same name elsewhere. The enforcement APIs differ, and one checkbox can mean strictly different things on a desktop and on a phone. Version matters too, because the lockdown control has moved between screens across Android releases, and a client-side exclusion list is not the same control as a platform lockdown.

Three Moments: Tunnel Up, Tunnel Down, Reconnected

Use harmless requests at three moments: while the tunnel works, during the failure you care about, and after reconnection. A single browser result cannot establish the excluded app's behaviour.

curl -sS --max-time 8 https://api.ipify.org
curl -sS --max-time 8 --interface tun0 https://api.ipify.org
dig +short example.com

The egress address shows which path was taken, and the explicit interface test shows what happens when the tunnel is the only available exit. Note the expected result beside each line before running any of them, or the output will be interpreted after the fact.

If an excluded app goes offline, inspect the policy precedence before adding a broad firewall allow, since that fix destroys the distinction you were testing. If it stays direct, confirm that this was the documented exception and not an accidental fallback. For a strict whole-device requirement, shorten the exception list until it can be tested by hand.

Sɛbɛn minnu bɛ tali kɛ