What is a PAC file?
A PAC (Proxy Auto-Config) file is a small JavaScript file that tells browsers and operating systems which proxy, if any, to use for each URL. Instead of one fixed proxy for everything, a PAC file lets you route some traffic through one proxy, other traffic through another, and send internal traffic directly.
PAC files are widely used in corporate networks and are supported by Windows, macOS, iOS, Android, Firefox and Chromium-based browsers.
The FindProxyForURL function
Every PAC file defines one function:
function FindProxyForURL(url, host) {
return "DIRECT";
}It returns a string describing what to do:
| Return value | Meaning |
|---|---|
DIRECT | Connect without a proxy |
PROXY host:port | Use an HTTP proxy |
HTTPS host:port | Use an HTTPS (TLS) proxy (supported by some browsers) |
SOCKS5 host:port | Use a SOCKS5 proxy |
PROXY a:8080; PROXY b:8080; DIRECT | Try in order, falling back |
Example rules
function FindProxyForURL(url, host) {
// Internal hosts go direct
if (isPlainHostName(host) ||
dnsDomainIs(host, ".internal.example.com") ||
isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0")) {
return "DIRECT";
}
// A specific site through a UK proxy
if (shExpMatch(host, "*.example.co.uk")) {
return "PROXY uk-proxy.example.net:8080";
}
// Everything else through the main proxy, falling back to direct
return "PROXY gate.example.com:7777; DIRECT";
}Helpful built-in functions include isPlainHostName, dnsDomainIs, shExpMatch, isInNet, dnsResolve, myIpAddress, weekdayRange and timeRange.
Hosting a PAC file
- Serve it over HTTP(S) with MIME type
application/x-ns-proxy-autoconfig. - Point devices to its URL in their proxy settings ("Automatic proxy configuration" / "Use setup script").
- Keep it small and fast; it runs for every request.
See Windows proxy setup, Mac proxy setup and iPhone and Android setup.
WPAD
Web Proxy Auto-Discovery (WPAD) lets devices find a PAC file automatically via DHCP or DNS (looking up wpad.<domain>). It's convenient in managed networks but has a history of security issues on untrusted networks; many organisations disable it unless they need it.
Authentication
PAC files can't contain proxy credentials. Browsers prompt for credentials when the proxy asks, or you use IP-based access. See proxy authentication methods.
Debugging tips
- Avoid
dnsResolvewhere possible; DNS lookups slow every request. - Test in multiple browsers; support for some return types varies.
- Chrome's
chrome://net-internals/#proxyshows the effective proxy settings and lets you re-apply them. - Syntax errors cause the whole PAC file to fail, often falling back to direct connections.
A PAC file for scraping and testing teams
Teams that test websites from different locations sometimes use PAC files to route specific domains through region-specific proxies while leaving everything else direct:
function FindProxyForURL(url, host) {
// Test sites routed by region
if (dnsDomainIs(host, ".example.de")) return "PROXY de-proxy.example.net:8080";
if (dnsDomainIs(host, ".example.co.uk")) return "PROXY uk-proxy.example.net:8080";
if (dnsDomainIs(host, ".example.fr")) return "PROXY fr-proxy.example.net:8080";
// Everything else direct
return "DIRECT";
}Team members point their browsers at one PAC URL and automatically see each regional site through the right country, without switching settings.
Proxy tip: When troubleshooting, it helps to have a second, known-good proxy to compare against. A small pay-as-you-go balance from Geonode works well for that, and its dashboard shows usage and active sticky sessions. More in using Geonode in your browser.
Load balancing and failover
A PAC file can spread users across proxies and fail over:
function FindProxyForURL(url, host) {
var proxies = ["PROXY p1.example.net:8080", "PROXY p2.example.net:8080"];
var i = (myIpAddress().split(".")[3] | 0) % proxies.length;
return proxies[i] + "; " + proxies[(i + 1) % proxies.length] + "; DIRECT";
}The browser tries the first proxy, then the second, then direct.
Performance considerations
- PAC logic runs for every request; keep it simple.
dnsResolveandisInNetwith hostnames trigger DNS lookups, which add latency.- Large lists of domains are better handled with
shExpMatchpatterns or by moving logic to the proxy server.
Testing PAC files
- Load the PAC file in the browser and visit test URLs.
- In Chrome,
chrome://net-internals/#proxyshows the effective configuration. - Use small test scripts in Node.js by defining stub implementations of PAC helper functions to unit-test your logic.
Security notes
- Serve PAC files over HTTPS where supported, so they can't be tampered with in transit.
- Restrict who can edit the PAC file; whoever controls it controls where users' traffic goes.
- Disable WPAD on untrusted networks.
For related setup guides, see browser proxy settings and forward vs reverse proxy.
PAC syntax quick reference
| Function | Example | Purpose |
|---|---|---|
isPlainHostName(host) | intranet | No dots in hostname |
dnsDomainIs(host, ".example.com") | www.example.com | Domain suffix match |
shExpMatch(host, "*.example.*") | Pattern match | Wildcards |
isInNet(ip, net, mask) | 10.0.0.0/8 | IP range check |
myIpAddress() | Client IP | Location-based rules |
weekdayRange("MON", "FRI") | Weekdays | Time-based rules |
timeRange(9, 17) | Office hours | Time-based rules |
Common mistakes
- Forgetting
returnin some code paths (falls back unpredictably). - Using
dnsResolveexcessively (slow). - Serving with the wrong MIME type.
- Caching issues: browsers may cache PAC files; change the URL or headers when updating.
See proxy setup on Windows and proxy setup on Mac.
Testing PAC logic from the command line
Clicking around a browser is a slow way to test a PAC file. pacparser includes pactester, which evaluates a PAC file the way a browser would and prints the result:
pactester -p proxy.pac -u https://www.example.com/
pactester -p proxy.pac -u http://intranet.example.com/ -c 10.0.0.5The -c option sets the client IP that myIpAddress() returns, so you can test rules that depend on which network the user is on.
Turn it into a regression test: keep a file of URLs with the result you expect for each, run them through pactester in a loop, and fail the build if any answer changes. That catches the classic PAC mistakes before users do: a missing DIRECT fallback, a domain rule that accidentally matches too much, or a typo that sends everything through the proxy.
Remember that browsers differ slightly in which helper functions they support and how they cache results, so finish with a real browser check on the platforms your users have. MDN's PAC file reference lists the standard functions. For rolling a PAC out to a team with SOCKS5, see best SOCKS5 proxies; for checking what the browser actually applied, browser proxy settings.
Key takeaways
- A PAC file is a JavaScript
FindProxyForURLfunction that chooses a proxy (or direct) per URL. - It supports routing by domain, network, time and fallback chains.
- Serve it with the correct MIME type and keep logic fast; avoid excessive DNS lookups.
- PAC files can't hold credentials.
- Disable WPAD on untrusted networks and protect who can edit the PAC file. See forward vs reverse proxy.
FAQ
Can PAC files use SOCKS5?
Yes, with SOCKS5 host:port, where the client supports it.
Are PAC files useful for scraping?
Rarely; scrapers set proxies in code. PAC files are mainly for browsers and managed devices.
Editorial note: Proxy providers change their pools, features and prices often, so treat any figures here as typical ranges at the time of writing and confirm current terms with the provider before you buy.