Two clients run at once, each convinced it owns the default route, and the symptom arrives as something strange: one guest application works, another resolves to the wrong place. A VPN inside a guest and a VPN on the host can coexist, but only when the outer path and the inner policy agree about who carries what. Starting both does not create a chain by itself. Record the attachment first, then change one thing at a time.

Record the Guest's Attachment First

The guest reaches its VPN server through whichever path the hypervisor gave it: NAT behind the host, a bridge onto the physical segment, or a host-only network with routing added on top. Each attachment changes what the guest can see and what the host can do to its traffic. Under NAT the guest's packets appear to come from the host, so the host's own tunnel may carry them without the guest knowing anything about it. Under a bridge the guest has its own presence on the segment and its own default gateway.

Write the attachment down before touching any configuration, together with which client is supposed to carry which application. That sentence resolves most of these tickets, because the two clients are usually built on different assumptions. A guest expected to use the host tunnel must not also have a competing default route of its own.

Follow the Guest Endpoint Outward

A guest VPN needs a usable path to its own server before anything else can work. When the host tunnel is up and the guest sits behind NAT, the guest's handshake leaves through the host tunnel, which is either the design or an accident nobody documented. When the host tunnel drops and the guest depended on it, the guest loses connectivity without a single change on its side. Tracing the endpoint outward tells you which of those you actually have.

A broad route in either context captures traffic the other client expected. A 0.0.0.0/0 route inside the guest and a full-tunnel host client both claim everything, and whichever applies last wins. Overlaps between guest virtual networks, the local LAN and remote networks produce the same effect for private prefixes, with failures that resemble authentication problems; the address-translation behaviour is the same one described for container networking.

Compare a Before and After Record

Take a baseline with the host tunnel off, or in whatever controlled state your policy permits, and record the guest's route and resolver. Then apply the combined configuration and compare the two records, keeping privacy requirements intact. If a direct baseline is not appropriate, write that limitation into the record instead of skipping the comparison.

ip route get 10.20.30.41
ip rule show
resolvectl status --no-pager | head -12

The route query names the interface and source address that would carry a specific destination, and it is the single most useful line in this investigation. The rule listing shows whether policy routing sends some destinations through a second table. The resolver output shows whether DNS followed the guest tunnel or stayed on the host's path. Run the same three commands before and after the change, and the delta names the culprit.

Keep Ownership Clear Across Restarts

A host client's local-access restriction can block traffic to a virtual NAT or bridge, and that restriction is routinely mistaken for a guest credential problem. Read the client's documented behaviour rather than disabling the restriction to make a test pass. After a supported correction, retest the guest application and the failure policy you require. A host that reconnects successfully proves nothing about the guest's route or resolver.

Decide which side owns the default route and write that in the runbook. A guest restart or a host network switch that silently reverses ownership produces a bug report about a VPN that was never at fault. The arrangement should survive a reboot without anyone remembering why it worked.

Mikanda mikatakata