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

Source: https://findproxyforurl.net/articles/zscaler-pac-file-checklist/ · updated 2026-10-06

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](https://findproxyforurl.net/check/) and choose **Zscaler** under
Environment. To start from a clean file instead, use the [Zscaler PAC builder](https://findproxyforurl.net/generate/sse/zscaler/).

## 1. Always return the gateway pair

```js
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](https://findproxyforurl.net/rules/zscaler-no-secondary-gateway/)).

## 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](https://findproxyforurl.net/rules/zscaler-service-edge-port/)).

## 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](https://findproxyforurl.net/rules/zscaler-unknown-pac-variable/)).

## 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](https://findproxyforurl.net/rules/zscaler-literal-gateway-address/)).

## 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](https://findproxyforurl.net/rules/zscaler-forwarding-and-app-pac-mixed/)).

## 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](https://findproxyforurl.net/rules/sse-local-traffic-not-bypassed/), [DNS in PAC files](https://findproxyforurl.net/articles/dns-in-pac-files/)):

```js
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](https://findproxyforurl.net/rules/sse-proxy-for-non-http-schemes/)).

## 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](https://findproxyforurl.net/rules/agent-intercepts-pac-direct-traffic/)).

## 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](https://findproxyforurl.net/rules/zscaler-client-connector-legacy-pac-parser/)).

## Check it

[Test your Zscaler PAC](https://findproxyforurl.net/check/) with the Zscaler vendor selected, or
start from a clean file with the [Zscaler PAC builder](https://findproxyforurl.net/generate/sse/zscaler/).


## 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.

