Your second client connects, the first one's resources stop resolving, and the ticket says the work VPN broke the personal one. Nothing is broken in the sense of a fault: both clients did what they were designed to do, and the machine has only one routing table. The collision is over four resources that each client assumes it owns. Work through them in order and the fix usually becomes a design choice rather than a repair.

Step 1: find which client owns the egress

Read the current egress decision before changing anything. The route lookup for a public address tells you which interface and next hop a packet would use right now, and that is the answer to who won. Compare it with the interface names the clients created, which usually carry the product or protocol name. If the lookup points at the tunnel you did not expect, you have already found the collision.

ip route get 1.1.1.1
ip route show default
route print

Some clients do not replace the default route at all; they add two halves, one for the lower half of the address space and one for the upper half, which together cover everything. That leaves the original default route visible and makes a manual repair look correct while traffic still leaves through the tunnel. Read the metric and the prefix length, not just the presence of a default entry.

Stop if both clients claim the same prefix with the same metric. The kernel will pick one, and the other will appear connected while carrying nothing.

Step 2: check the resolver and the overlapping prefixes

DNS is the second collision, and it produces a distinctive symptom: names fail while addresses work. Each client pushes its own resolver, and the last writer wins for the queries that follow. Ask the resolver service what it uses per link rather than reading the client's settings page.

resolvectl status
Get-DnsClientServerAddress
dig +short intranet.corp.example

Then compare the private prefixes the two networks use. If both sides allocate from the same range, no client-side arrangement will fix it, because the machine cannot tell which 10.0.0.0/8 destination belongs to which tunnel. One side has to be renumbered or translated, and that is a conversation with the network owners rather than a configuration change. Overlap is the one collision where the honest answer is that the design has to change.

Stop here if the prefixes overlap. Everything later in this checklist assumes they do not.

Step 3: pick a separation pattern that holds

The reliable patterns avoid running two clients against the same routing table. One client with a split-tunnel policy that reaches both private networks is the simplest, provided the destinations do not overlap and the policy owner agrees. A virtual machine or a network namespace is the next step up, because each gets its own table and its own resolver.

sudo ip netns add vpn2
sudo ip netns exec vpn2 ip link show
sudo ip netns exec vpn2 curl -sI https://intranet.corp.example/

A namespace gives the same separation as a virtual machine without the second operating system, but it has rough edges: the tunnel device has to be moved into it, and the application must be started inside it. A separate physical device is often the least surprising option for a personal VPN alongside a managed work client. Stacking one tunnel inside another is not a separation pattern; the inner endpoint has to stay reachable through the outer tunnel, and the arrangement adds MTU and latency problems on top.

Choose one pattern and write down why. Mixing a namespace for one application with a split tunnel for the rest recreates the original collision in a harder-to-debug form.

Step 4: verify both networks from the same session

Test one resource on each private network from the environment where the application actually runs, not from your shell if the app runs inside a namespace. Check the egress interface, the resolved address and the response code together, because a success in one of the three can hide a failure in the others. Repeat after a reboot, since the order in which clients start decides which one wins. That ordering is the part people forget to record.

curl -sI https://intranet.corp.example/
curl -sI https://files.personal.example/
ip route get 10.20.30.40

Record the client versions, the interfaces, the resolver state and the prefixes for each network. When a client updates and changes its route behaviour, that record is the difference between a five-minute fix and a rebuild. The next person will not share your memory of which tunnel came up first.

The checklist is complete when you can name the interface that owns the default route, the resolver each name uses, the pattern that separates the second tunnel, and the result of one request per network after a reboot. Anything less is a configuration that happens to work today.

Related articles