Forwarding Profile and App Profile roles mixed in one Zscaler Client Connector PAC
high
Zscaler Client Connector uses two PAC files with different jobs. The Forwarding Profile PAC steers traffic to the client (${ZAPP_LOCAL_PROXY}) or around it; the App Profile PAC sends what the client received to the cloud (${GATEWAY}). A file that does both is used in the wrong slot somewhere.
Why it matters
In Tunnel mode Zscaler’s guidance is explicit: use the Forwarding Profile PAC only to bypass traffic
away from Zscaler Client Connector or to steer it to the client, never to tunnel traffic to the
Zscaler cloud. In Tunnel with Local Proxy mode the Forwarding Profile PAC must return
PROXY ${ZAPP_LOCAL_PROXY}, which the client replaces with its loopback listener, and the App Profile
PAC then chooses the data centre with ${GATEWAY}. When one file contains both ${ZAPP_LOCAL_PROXY}
(or ${ZAPP_TUNNEL2_BYPASS}) and ${GATEWAY}, either the browser is sent straight to a Public
Service Edge, skipping the client and its tunnel, or the client is asked to forward to itself.
Keep the two files separate and keep the App Profile PAC as simple as possible.
How to fix
Split the file. Forwarding Profile PAC returns ${ZAPP_LOCAL_PROXY} / ${ZAPP_TUNNEL2_BYPASS} and DIRECT only; the App Profile PAC returns ${GATEWAY} / ${SECONDARY_GATEWAY} and the cloud-side exceptions.
Examples
Bad
function FindProxyForURL(url, host) {
if (isPlainHostName(host)) {
return "DIRECT";
}
if (dnsDomainIs(host, ".partner.example.net")) {
return "PROXY ${GATEWAY}:80; PROXY ${SECONDARY_GATEWAY}:80";
}
return "PROXY ${ZAPP_LOCAL_PROXY}";
}
Open bad example in checkerGood
function FindProxyForURL(url, host) {
if (isPlainHostName(host)) {
return "DIRECT";
}
return "PROXY ${ZAPP_LOCAL_PROXY}";
}
Open good example in checker