# Windows runs PAC files differently from Chrome and Firefox

Source: https://findproxyforurl.net/articles/pac-on-windows/ · updated 2026-10-11

Changed 2026-10-11: The rating now follows the Windows lab results of 2026-10-11: syntax newer than ES2017, such as ?. and ??, caps the grade at D, let and const only lower the score, and dateRange, timeRange, lower-case weekday names, decisions by URL path, SOCKS keywords, regex characters in shExpMatch and UTF-16 files are flagged.

Chrome, Edge and Firefox run a PAC file in their own engine. Windows services and many Windows programs run it in the Windows engine instead, and that engine answers some calls in its own way. A file that works in the browser can send these programs to the wrong place.

*Source for every statement on this page: lab, Windows 11 25H2, 2026-10-11.*

## Windows has its own PAC engine

A PAC file (proxy auto-config file, often called `proxy.pac` or `wpad.dat`) is a small JavaScript
program. Each client runs it to decide which proxy to use for an address. Chrome and Edge run it in
their own engine, also on Windows. Windows services, the background download service BITS, and
programs that use the Windows proxy settings run it in an engine that is part of Windows. Programs
reach that engine through WinHTTP and WinINet, the two network libraries of Windows, or through .NET
and Java.

The points below are the places where that engine answers differently from Chrome and Firefox.
Each one can make a file that passes a browser test go wrong for Windows programs.

## dateRange and timeRange are always false on Windows

On Windows, [dateRange()](https://findproxyforurl.net/functions/daterange/) and [timeRange()](https://findproxyforurl.net/functions/timerange/) returned
false for every form of argument, even for ranges that cover the whole day or the whole year. A rule
that depends on the date or the time therefore never applies to Windows programs, while it works in
the browsers ([PAC-K007](https://findproxyforurl.net/rules/time-functions-usage/)). The article [dateRange and timeRange are
always false on Windows](https://findproxyforurl.net/articles/pac-time-functions-windows/) explains what to do instead.

## weekdayRange on Windows needs upper-case day names

[weekdayRange()](https://findproxyforurl.net/functions/weekdayrange/) works on Windows, including ranges across the weekend such
as `weekdayRange("FRI", "MON")`. It accepts only upper-case day names such as `"MON"`. With
`weekdayRange("mon", "fri")` the call throws an error, which stops the script, while Chrome just
returns false.

## shExpMatch on Windows is a plain wildcard match

On Windows, [shExpMatch()](https://findproxyforurl.net/functions/shexpmatch/) knows only two special characters: `*` for any
text and `?` for one character. Characters that have a meaning in a regular expression (the pattern
language that the browsers use inside this function), such as `[ ] + ( ) $ |`, are compared as
ordinary characters on Windows. A pattern like `"[ab]bc"` therefore matches different strings on
Windows and in Chrome ([PAC-K015](https://findproxyforurl.net/rules/regex-syntax-in-shexpmatch/)). The match is case-sensitive,
as in the browsers.

## Newer JavaScript makes the whole file fail on Windows

The Windows engine understands JavaScript up to about the 2017 version of the language. `let`,
`const`, arrow functions, classes and template strings work. Optional chaining (`a?.b`), the `??`
operator and object spread (`{...o}`) are syntax errors, and then Windows cannot run the file at all,
for any address ([PAC-K020](https://findproxyforurl.net/rules/es2018-syntax/)). Some newer built-in functions, such as
`replaceAll` and `Object.fromEntries`, do not exist there either
([PAC-K010](https://findproxyforurl.net/rules/es2015-builtins/)).

## A badly written return value sends Windows programs direct

The function `FindProxyForURL` returns a text such as `"PROXY proxy.corp.example:8080; DIRECT"`.
If the `;` between two entries is missing, Windows goes direct, and Chrome does the same. Lower-case
keywords are where Windows differs: Chrome accepts `"proxy p.corp.example:3128"`, but Windows ignores
the entry and goes direct ([PAC-E011](https://findproxyforurl.net/rules/invalid-return-value/)). Write the keywords `PROXY`,
`DIRECT` and `SOCKS` in upper case and separate the entries with `;`.

## Older Windows programs drop SOCKS and everything after DIRECT

Programs built on .NET Framework or .NET receive only the proxies listed before the first `DIRECT`,
and they receive no SOCKS proxy at all. A PAC answer
that contains only a SOCKS proxy therefore sends them direct
([PAC-K005](https://findproxyforurl.net/rules/socks-version-keyword/), [PAC-X014](https://findproxyforurl.net/rules/direct-fallback-in-proxy-list/)).
Put an HTTP proxy (`PROXY`) first if these programs have to use a proxy.

## Windows keeps one answer per host and does not look at the path again

Windows runs the script once for a host and reuses the answer for later addresses on the same host,
even when the path or the port is different. A rule that sends `/download/` to another proxy than
the rest of the host is therefore not checked again. For `https://` addresses the script never sees
the path anyway, because Windows passes only the scheme, the host and the port
([PAC-K021](https://findproxyforurl.net/rules/url-path-decision/)). Some programs, such as Java, do not pass the path of
`http://` addresses either.

## An endless loop blocks Windows programs because there is no time limit

Windows does not stop a PAC script that runs too long. In the lab, a script with an endless loop
blocked the waiting program for more than 18 minutes, until it was stopped by hand
([PAC-E008](https://findproxyforurl.net/rules/potentially-infinite-loop/), [PAC-E007](https://findproxyforurl.net/rules/evaluation-timeout/)). Make sure
that every loop in the file ends.

## Some Windows programs keep upper-case letters in the host name

The host name that the script receives is not always in lower case on Windows. It depends on the
program: Windows
services and BITS pass the host as it was typed, for example `Example.COM`, while WinINet, .NET and
Java programs pass it in lower case. Because [dnsDomainIs()](https://findproxyforurl.net/functions/dnsdomainis/) and
`shExpMatch()` are case-sensitive, call `host = host.toLowerCase();` at the start of the file
([PAC-K009](https://findproxyforurl.net/rules/host-not-lowercased/)).

## Test the file with the Windows profile

The [PAC file tester](https://findproxyforurl.net/check/) has two Windows profiles: "Windows WinHTTP" for Windows services,
BITS and programs that use WinHTTP, and "Windows WinINet" for desktop programs,
.NET and Java programs that follow the Windows proxy settings. Paste your file, enter a URL and pick a Windows profile. The trace shows
which test and which line decided, and the rating flags the calls that Windows answers differently.
The engine pages for [Windows (WinHTTP)](https://findproxyforurl.net/engines/winhttp/) and
[Windows WinINet](https://findproxyforurl.net/engines/wininet/) list the details, and
[pactester vs Chrome and Firefox](https://findproxyforurl.net/articles/pactester-vs-chrome-firefox/) covers the other engines.


## Frequently asked questions

### Why does my PAC file work in Chrome but not in Windows programs?

Chrome and Edge run the PAC file in their own engine, also on Windows. Windows services and programs that use the Windows proxy settings run it in the Windows engine, which answers some calls differently. dateRange and timeRange are always false there, weekdayRange stops the script on lower-case day names, and newer JavaScript such as ?. or ?? makes the whole file fail. Test the file with a Windows profile in the tester at findproxyforurl.net/check/.

### Does WinHTTP support let and const in a PAC file?

Yes. In the lab on Windows 11 25H2, let, const, arrow functions, classes and template strings worked. Newer syntax such as optional chaining (?.), the ?? operator and object spread ({...o}) is a syntax error, and then the whole file fails.

### Is shExpMatch case-sensitive on Windows?

Yes, as in the browsers. On Windows, shExpMatch is a plain wildcard match in which only * and ? are special. Characters that mean something in a regular expression, such as [ ] + ( ) and $, are compared as ordinary characters, so some patterns match on Windows and not in Chrome, or the other way round.

### Why do some Windows programs ignore the SOCKS proxy in my PAC file?

Older Windows programs, for example those built on .NET Framework or .NET, receive only the proxies that come before the first DIRECT and receive no SOCKS proxy at all. A PAC answer with only a SOCKS proxy sends them direct.

### Does Windows run the PAC file again for every URL?

No. Windows keeps one answer per host and reuses it for other paths and ports on the same host, so a rule that looks at the path is not checked again. For https addresses the script never sees the path at all.

