Zscaler PAC file checklist: gateways, ports, variables and Client Connector

Published

A Zscaler PAC file fails in ways a generic PAC check does not see. A gateway on the wrong port, a misspelt ${GATEWAY} variable or a mixed-up Client Connector profile all end in the same place, users browsing without Zscaler. Here are the eight checks we run, each based on Zscaler's own documentation.

Each check links to its rule. The rule page quotes and links the Zscaler documentation it is based on (source: doc, Zscaler Help pages as cited in our rule catalogue, October 2026). To run all of them at once, paste your file into the PAC file tester and choose Zscaler under Environment. To start from a clean file instead, use the Zscaler PAC builder.

1. Always return the gateway pair

return "PROXY ${GATEWAY}:80; PROXY ${SECONDARY_GATEWAY}:80";

${GATEWAY} is the closest Public Service Edge and ${SECONDARY_GATEWAY} the next one. With only the primary, a data-centre outage leaves browsers without a proxy (PAC-B012).

2. Use a documented port

Public Service Edges accept browser traffic on 80, 443, 9400, 9443 and 9480, plus dedicated ports by subscription. :8080 or :3128 on a ${GATEWAY} entry fails, and the browser moves to the next entry. If that entry is DIRECT, the user is online without Zscaler (PAC-C019).

3. Spell the variables exactly

Only documented variables are replaced, such as ${GATEWAY}, ${SECONDARY_GATEWAY}, the COUNTRY_ forms, the _HOST, _F0–_F7 and _FX suffixes, and ${ZAPP_LOCAL_PROXY}. They are only replaced when the file is hosted on the Zscaler cloud. ${GATWAY} stays literal, and browsers skip the invalid entry (PAC-E019).

4. Prefer variables to literal gateway addresses

Zscaler discourages hard-coded gateway IPs because they can change. Literal host names skip the PAC server’s per-client selection of the closest healthy gateway (PAC-K016).

5. Keep Forwarding Profile and App Profile PACs apart

Zscaler Client Connector uses two PAC files with different jobs. The Forwarding Profile PAC returns ${ZAPP_LOCAL_PROXY} or DIRECT. The App Profile PAC returns ${GATEWAY} / ${SECONDARY_GATEWAY}. A file that does both is wrong in one of the two slots (PAC-C020).

6. Send local traffic direct, first

Plain host names and private addresses cannot be reached through the cloud proxy. Put these exclusions at the top, without DNS lookups (PAC-C026, DNS in PAC files):

if (isPlainHostName(host)) {
  return "DIRECT";
}
if (/^\d+\.\d+\.\d+\.\d+$/.test(host) &&
    (isInNet(host, "10.0.0.0", "255.0.0.0") ||
     isInNet(host, "172.16.0.0", "255.240.0.0") ||
     isInNet(host, "192.168.0.0", "255.255.0.0"))) {
  return "DIRECT";
}

Zscaler’s samples also exclude ftp: URLs, because the service does not proxy native FTP (PAC-C023).

7. A DIRECT in the PAC does not bypass Client Connector

In Tunnel mode, Client Connector intercepts ports 80 and 443 after the PAC has decided. A domain that must really bypass Zscaler also needs a bypass in the App Profile PAC or in the destination exclusions (PAC-B014).

8. Write ES5 for older Client Connector versions

Client Connector evaluates its PAC files itself. Versions before 4.9 on Windows (4.3 on macOS) could use a legacy parser whose JavaScript level Zscaler does not document. Avoid let, const, arrow functions and template strings (PAC-K017).

Check it

Test your Zscaler PAC with the Zscaler vendor selected, or start from a clean file with the Zscaler PAC builder.

Frequently asked questions

Which ports can a Zscaler PAC file use for ${GATEWAY}?

Zscaler documents 80, 443, 9400, 9443 and 9480 for Public Service Edges, plus dedicated ports your organisation subscribes to. Any other port is a dead end, so the browser fails over to the next entry.

Why does my Zscaler PAC return PROXY ${GATEWAY}:80 literally?

The variables are only replaced when the PAC is hosted on the Zscaler cloud, and only when they are spelt exactly as documented. A self-hosted file or a typo such as ${GATWAY} leaves an invalid entry that browsers skip.

How do I test a Zscaler PAC file?

Paste it into findproxyforurl.net/check/, open "Environment" and choose Zscaler as the security service edge vendor. The tester then applies the Zscaler checks below on top of the generic rules.