IPv6 in PAC files: isInNet, isInNetEx and what actually works
Most PAC files were written for IPv4, and their helper functions were too. On dual-stack networks that leads to quiet surprises. IPv6 literals go to the proxy, isInNet is never true for them, and the IPv6 functions exist only in some engines.
Three facts to start with
isInNetis IPv4 only.isInNet(host, "fd00::", "ffff::")is never true (PAC-K014).- The
*Exfunctions are not portable.isInNetEx,dnsResolveEx,myIpAddressEx,isResolvableExandsortIpAddressListcome from Microsoft’s IPv6 extensions. Chromium implements them (source: code, verified 2026-10-04). Firefox does not have them, so a call throws and the request goes direct (PAC-K003; see the function availability table). FindProxyForURLExis ignored by browsers. Chromium and Firefox only callFindProxyForURL(source: code, verified 2026-10-04). A file that only defines the Ex entry point does nothing in a browser (PAC-K004).
The usual symptom
The PAC sends 127.0.0.0/8 and the RFC 1918 ranges direct, but has nothing for ::1, link-local or
unique-local addresses. An IPv6 literal fails the IPv4 regular expression and takes the default
route, usually the proxy, where the connection fails. The tickets read “works with the IP, not with
the name” or the reverse (PAC-C012).
Portable handling
String tests work in every engine and need no DNS:
function FindProxyForURL(url, host) {
host = host.toLowerCase();
// IPv6 loopback, link-local and unique-local literals go direct
if (host == "::1" || shExpMatch(host, "fe80:*") ||
shExpMatch(host, "fc*:*") || shExpMatch(host, "fd*:*")) {
return "DIRECT";
}
// ... IPv4 and name rules ...
return "PROXY proxy.corp.example:8080";
}
Whether engines pass IPv6 literals in host with or without brackets has not been confirmed in our
lab for every engine yet (source: expert, unverified). Test with your client, or add both forms.
If you really need isInNetEx, guard it:
if (typeof isInNetEx === "function" && isInNetEx(host, "2001:db8::/32")) {
return "DIRECT";
}
Proxy addresses
Return proxies by name, not by IPv6 literal. Some services do not accept IPv6 in PROXY
statements at all. Palo Alto Networks’ PAC file guidelines for Prisma Access say so explicitly
(PAC-K019).
Check your file
The PAC file tester flags *Ex calls, IPv6 networks in isInNet and missing IPv6
exceptions, and shows where Chromium and Firefox disagree.
Frequently asked questions
Does isInNet work with IPv6?
No. isInNet parses dotted-quad IPv4 addresses and masks. With an IPv6 network or mask it is false in every engine.
Can I use isInNetEx in a PAC file?
Only where the engine provides it. Chromium and WinHTTP implement the Microsoft IPv6 extensions; Firefox does not, so an unguarded call throws there and the request goes direct. Guard it with typeof isInNetEx === "function" and provide a fallback.
How do I send local IPv6 addresses direct?
Use string tests on host, which are portable. Check host == "::1" for loopback, and shExpMatch(host, "fe80:*"), "fc*:*" or "fd*:*" for link-local and unique-local addresses.