Routing the application's subnet is the obvious part of a split tunnel, and it is not the whole job. The resolver often sits on a different address than the application it serves, so a working tunnel can still leave the lookup outside it. A profile that carries 10.80.0.0/16 and nothing else sends the query for 10.90.0.53 out of the local interface, where no private zone exists. Add the resolver path, then check the second half of the problem: which server the client actually chooses.

The myth: one route covers the whole service

A split tunnel is a list of destinations that go through the connection, not a description of a service. The application subnet and the resolver address are two destinations, and a profile can carry one without the other. When that happens, the application is reachable by address while its name fails, which looks like a DNS fault rather than a routing gap.

The resolver's surrounding subnet is not automatically covered either. A host route to a single address is enough for that resolver and does not open its neighbours. That is the point of a host route: narrow by design, and easy to forget when the next service appears on the same subnet.

Three things must hold for the lookup to work: the client routes the resolver address through the tunnel, the gateway admits and forwards that request, and the resolver accepts the source it receives. A reply also has to come back by the agreed path. Miss any one of those and the symptom is identical, which is why the address table is worth writing down before touching a configuration.

Work out which addresses the profile must carry

List the destinations in order: the application network, the resolver address, and the public endpoint that terminates the tunnel itself. The third one must never be routed into the tunnel, because the outer connection needs a path that exists before the tunnel does.

DestinationCoverage this example needs
Application network10.80.0.0/16 through the VPN
Private resolver10.90.0.53/32 through the VPN
Public VPN endpointNormal internet path, outside the tunnel

Include both UDP and TCP for DNS, since implementations are expected to support TCP as well as UDP and a blocked TCP path produces slow, partial failures rather than clean ones. If the private zone is served over IPv6 as well, the equivalent host exception uses an IPv6 address and prefix and is a separate entry.

Record what the profile already covers before adding anything. A duplicate route is harmless, but an unexpected existing route tells you the profile was designed for a different address plan than the one you were given.

Add the host route through the connection owner

For a locally managed native Windows profile, the route belongs to the connection rather than to the machine's global routing table. Preview the addition first, then apply it with the same scope the profile uses.

Add-VpnConnectionRoute -ConnectionName 'Office VPN' -DestinationPrefix '10.90.0.53/32' -WhatIf
Get-VpnConnection -Name 'Office VPN' | Select-Object -ExpandProperty Routes

The first command previews the change without installing anything, and the second lists the routes the profile currently carries. Microsoft's Add-VpnConnectionRoute reference documents the per-user and all-user scopes; an all-user profile needs its own scope parameter, and a per-user command against an all-user profile fails or lands in the wrong place.

When the profile is managed or comes from a vendor client, the change belongs to that owner. Stacking a permanent system route on top of a connection policy works until the policy is reapplied and the route is gone, which usually happens during a support call rather than during testing. That failure is silent: the route disappears, the name stops resolving, and nobody connects the two events. Put the change into the owner's own record so the next reapply carries it instead of erasing it.

After applying, reconnect the profile rather than assuming the route took effect. Route changes on a live connection are not always picked up, and a reconnect also reproduces the state your users will actually have.

Check which resolver the client actually used

A route controls packets addressed to the resolver. It does not decide which names should be sent there, and that selection is a separate mechanism. On Windows, effective namespace rules can choose a resolver per domain, while the profile's DNS settings supply a default. Those two layers can disagree without producing any error, which is why a direct query is only half the evidence.

Get-DnsClientNrptPolicy
Resolve-DnsName app.svc.example -Server 10.90.0.53 -Type A

The first command prints the namespace policy in force, and the second asks the private resolver directly for the application name. A direct answer proves the path and the resolver work; it does not prove the application's own lookup selected that server. Compare it with a normal lookup of the same name and with the answer the application receives.

Account for caches and for browser-level secure DNS, which can bypass the system resolver entirely for names a user typed. A search suffix is another red herring: it expands a short name into a fully qualified one and has nothing to do with which server answers.

Finish by reconnecting and repeating the normal lookup, then confirm that ordinary browsing still follows its approved policy. Replacing the private resolver with a public one to make an unrelated name resolve is not a fix, and it quietly moves private queries somewhere they were never meant to go.

Artitgels cun il medem tema