* * deny — ~/blog/trusted-network-detection

Why your on-net detection flaps during network transitions

A laptop comes off the dock and joins Wi-Fi. For a few seconds it isn't on the corporate network and isn't off it either — it's in the middle of changing its mind. Zscaler Client Connector has to answer one question in that window: trusted network, or untrusted? Get it wrong and the endpoint forwards traffic the way the other answer says to, which shows up as a minute of weirdness nobody can reproduce and nobody files a ticket about.

The answer comes from Trusted Network Criteria: seven conditions you configure in the admin portal. One of them is the one most people set up first, because it's the one that's easiest to explain to yourself. It's also the one Zscaler's own documentation tells you, in writing, to prefer something else over.

what the trusted verdict controls

Trusted-network detection isn't a status light. It selects behavior. Zscaler's own phrasing for the failure mode is that the app "applies the wrong forwarding profile action" — and a forwarding profile's action is the big lever. Per About Forwarding Profiles, the documented actions include Tunnel, Tunnel with Local Proxy, PAC, None (defer to whatever GPO or the browser already says), Direct Internet Access, and Disable Internet Access.

Those are not small differences. Tunnel and None send the same packet to completely different places. A detection flap isn't cosmetic: the endpoint changes how it reaches the internet, mid-session, on the strength of a question it answered wrong.

the seven criteria (and the field that isn't one)

Open Add Trusted Network and the form has two sections. Network Definition holds Network Name — a label so you can tell your entries apart in a list. It matches nothing. Trusted Network Criteria holds the conditions Client Connector evaluates, and there are seven of them (Configuring Trusted Networks for Zscaler Client Connector):

criterianote
DNS Serverstatic — recommended
DNS Search Domainsstatic — recommended
Hostname and IPdynamic — see below
Network Range
Default Gateway
DHCP Server
Egress IPZCC 4.6+, Windows only

Two details in that list carry more weight than their size suggests. DNS Search Domains only verifies the primary domains assigned to the active network adapter — so if your trust decision leans on a secondary suffix, it isn't being checked. And Egress IP applies only to Client Connector 4.6 and later on Windows, which means one can sit in the admin UI looking configured and do nothing on the part of your fleet running an older build or a Mac.

DNS Server is the plainest of the set: you enter the DNS servers your corporate network sends requests to, and the app verifies at least one of them.

before you count them yourself Network Name looks like one of the criteria and gets counted as an eighth all the time — I did it in my own first pass at this. It sits in a different section of the form, and it's a label. Seven.

the one that has to ask a question

Hostname and IP is the one people configure first, and it's easy to see why. Everyone has an internal hostname that only resolves on the corporate network. Point the check at it, list the IP it should come back as, done. It reads like a perfect test.

Zscaler documents the problem with it directly:

configuring trusted networks for zscaler client connector "Zscaler recommends using static properties, such as DNS Server and DNS Search Domains, for Trusted Network Criteria. In contrast, Hostname and IP resolution is a dynamic property because Zscaler Client Connector must resolve a hostname to see if it resolves to the IP address specified in Trusted Network Criteria. There is a chance that a resolution might fail because of network transition processes. If a resolution fails, the app could incorrectly determine that the network is an untrusted one, in which case it applies the wrong forwarding profile action."

Static vs. dynamic is the distinction to hold onto. A static property is a value Client Connector reads off the adapter: what DNS servers are configured, what the search domains are. Reading a value either works or the adapter isn't up yet. Hostname and IP has to send a query and wait for an answer, over the network whose identity it is currently trying to establish.

And the failure direction is the bad one. A failed resolution doesn't return "unknown" and hold the previous verdict. It reads as not matching, which reads as untrusted. So the check that's supposed to prove you're on the corporate network is the check most likely to break during the ten seconds where you're joining the corporate network.

The docs say "network transition processes" and don't enumerate them, so I won't put words in their mouth. But the shape is ordinary networking: an adapter comes up before DHCP has finished, the DNS servers on the interface are still the old ones or none, a wake from sleep re-runs everything at once. Any window where a query can be issued and fail is a window where this one votes "untrusted."

any vs. all is the whole game

Multiple criteria can be combined two ways: Any (match one and the network is trusted) or All (every condition must match). This is where the dynamic-condition problem gets either contained or amplified, and it's a two-click decision that most people make without thinking about it.

  • All, with Hostname and IP in the set: one failed resolution takes the entire verdict down, no matter how many static criteria matched cleanly. You've made your most fragile input a veto.
  • Any, with Hostname and IP in the set: a failed resolution costs nothing as long as one other condition matched. The fragile input becomes a bonus vote instead of a veto.

That's the fix, and it's cheap. If Hostname and IP is covering something nothing else covers, you don't have to delete it. You have to stop letting it be load-bearing: move it out of an All set, or keep the All set to static properties only.

The reverse caution is a security one. Any means a single matching condition declares the network trusted, so a condition that's easy to satisfy off-network is a weaker statement than it looks when it's the only vote that has to land.

VPN gets its own trust category

The intuition almost everyone has here is that a VPN connection makes an off-network machine look on-network, tripping the same trusted criteria from the far side. That's not the model. Client Connector tracks VPN as a separate trust state.

Zscaler's Location-Based Policy announcement (November 16, 2025) lists four trust categories, not two: Off-Trusted, On-Trusted, VPN-Trusted, and Split-VPN Trusted. Each gets its own policy ruleset per location, configured independently. The post's own framing is that "Client Connector detects the trust status of a location based on customer-defined criteria."

VPN-Trusted has its own input as well. Rather than inferring VPN state from network conditions, you name the adapter: the VPN-Trusted Network Adapter Criteria field takes your VPN client's adapter or vendor name, and Client Connector uses that to classify the network as VPN-Trusted. Split-tunnel VPN is a separate toggle — Enable Split VPN-Trusted Network — so a split-tunnel connection can be detected as its own thing rather than being lumped in with a full-tunnel one.

One thing I could not source, and I looked: what VPN-Trusted does before you've configured a ruleset for it. It's widely repeated that it inherits On-Trusted behavior by default. I read the announcement post in full and it doesn't say that — if anything the point of the feature is that each category gets its own explicit ruleset. I couldn't find primary documentation either way, so treat the default as unknown and check your own tenant rather than assuming your VPN users land on your on-network policy.

There's also a documented interaction worth knowing if you run a third-party VPN alongside the agent: Zscaler's interoperability guidance says to avoid the route-based Tunnel action for a VPN-Trusted network, because route-based tunneling and a VPN client both operate at the IP layer and compete for it. Tunnel with Local Proxy or a packet-filter-based tunnel work at the application layer and don't.

what to configure

Lead with static properties. The docs name DNS Server and DNS Search Domains specifically. Those are values read off the adapter, not questions asked over a network that may not be ready to answer yet.

If you keep Hostname and IP, don't let it veto. In an All set it is a single point of failure with a documented failure mode. In an Any set it's harmless. Same check, completely different blast radius.

Confirm whatever you pick applies to the whole fleet before you rely on it. Egress IP is 4.6+ and Windows. DNS Search Domains only looks at primary suffixes on the active adapter. Both of those look configured in the portal whether or not they're doing anything on a given endpoint.

Configure all four trust states deliberately. Off-Trusted, On-Trusted, VPN-Trusted, Split-VPN Trusted. Three of them are easy to leave at whatever they came as, and one of those three is how your remote users with a corporate VPN get treated.

the bigger lesson

The easiest thing to configure and the most reliable thing to configure are rarely the same thing, and the gap between them is where hard-to-reproduce problems come from. Hostname and IP is legible — you can explain it to a manager in one sentence. Reading DNS servers off an adapter is boring and doesn't demo well. The boring one doesn't have a failure mode written into the vendor's own documentation.

If your on-net detection flaps and nobody can reproduce it, go look at whether a resolution is being asked to happen during the exact seconds the network is changing underneath it — and whether your matching mode turned that question into a veto.