Troubleshooting Proxy Auto Config: Common Issues and Fixes

A Beginner’s Guide to Proxy Auto Config (PAC) for DevelopersProxy Auto Config (PAC) files are a simple but powerful tool for controlling how browsers and other HTTP clients choose proxies for different destinations. For developers, understanding PAC files helps with debugging network behavior, implementing granular routing rules, and supporting complex corporate or testing environments. This guide explains what PAC files are, why they matter, how they work, and how to write, test, and deploy them effectively.


What is a PAC file?

A PAC file is a JavaScript file that defines a single function, FindProxyForURL(url, host). When a browser or client is configured to use a PAC file, it calls this function for each request. The function returns a string that tells the client which proxy (or direct connection) to use.

  • Format: JavaScript
  • Function name: FindProxyForURL(url, host)
  • Return value: A proxy string like “PROXY proxy.example.com:8080” or “DIRECT”, or a sequence like “PROXY p1:8080; PROXY p2:8080; DIRECT”.

Why developers should care

  • Debugging: PAC files can reveal why certain traffic goes through a proxy or bypasses it, helping diagnose issues with authentication, caching, or access.
  • Testing and staging: Route only specific hosts to staging environments or local proxies without changing system-wide proxy settings.
  • Performance: Bypass proxies for local or performance-sensitive hosts to reduce latency.
  • Security and compliance: Force traffic for certain domains through monitoring or filtering proxies.

Anatomy of FindProxyForURL

The function signature:

function FindProxyForURL(url, host) {     // logic here     return "DIRECT"; } 

Return values (can be chained with semicolons):

  • “DIRECT” — connect without a proxy.
  • “PROXY host:port” — use an HTTP proxy.
  • “SOCKS host:port” or “SOCKS5 host:port” — use a SOCKS proxy.
  • Multiple entries allow fallback (try first, then next).

Useful built-in PAC helper functions

PAC environment provides multiple helper functions to simplify rules. Common ones:

  • dnsDomainIs(host, domain) — true if host ends with domain
  • shExpMatch(str, shexp) — wildcard matching (e.g., “*.example.com”)
  • isInNet(ipaddr, pattern, mask) — match IPv4 address ranges
  • dnsResolve(host) — resolve hostname to IP (may return null)
  • myIpAddress() — get client IP address
  • weekdayRange(), dateRange(), timeRange() — schedule-based rules

Example usages:

if (dnsDomainIs(host, ".internal.example.com")) return "DIRECT"; if (shExpMatch(url, "https://*.staging.example.com/*")) return "PROXY staging-proxy:8080"; 

Common patterns and examples

  1. Bypass local network and internal domains:
function FindProxyForURL(url, host) {   // Local names   if (shExpMatch(host, "*.local") || host.indexOf(".") == -1) return "DIRECT";   // Internal domain   if (dnsDomainIs(host, ".internal.example.com")) return "DIRECT";   // Default proxy   return "PROXY proxy.example.com:3128; DIRECT"; } 
  1. Use a proxy for all HTTP, direct for HTTPS (not recommended for security, shown for pattern):
function FindProxyForURL(url, host) {   if (url.substring(0, 5) == "http:") return "PROXY proxy.example.com:8080";   return "DIRECT"; } 
  1. Geo/IP-based logic (using DNS resolution + isInNet — note DNS-based geolocation is limited):
function FindProxyForURL(url, host) {   var ip = dnsResolve(host);   if (ip && isInNet(ip, "10.0.0.0", "255.0.0.0")) return "DIRECT";   return "PROXY proxy.example.com:3128; DIRECT"; } 
  1. Failover proxies:
function FindProxyForURL(url, host) {   return "PROXY p1.example.com:8080; PROXY p2.example.com:8080; DIRECT"; } 

Testing PAC files locally

  • Browser testing: Set browser to use “Automatic proxy configuration” and provide a file:// or http:// URL pointing to your PAC file.
  • Tools:
    • curl: not native support for PAC; use proxy specification directly or tools that evaluate PAC.
    • pacparser (library/CLI) — evaluate PAC files programmatically.
    • Online PAC testers (for quick checks).
  • Chrome: Developer Tools > Network tab will show proxy used; chrome://net-internals can help diagnose (may vary by Chrome version).
  • Firefox: about:config, set network.proxy.autoconfig_url and use about:networking for diagnostics.

Security considerations

  • PAC files are JavaScript — they can include any logic but run in a restricted environment. Avoid hosting PAC files on untrusted servers; clients automatically fetch them and will execute the logic.
  • If the PAC file is served over HTTP, it can be tampered with. Serve PAC files over HTTPS and use strong hosting controls.
  • Avoid embedding sensitive credentials or secrets in PAC logic.
  • Beware of DNS-based logic: dnsResolve can leak DNS queries and may be manipulated by poisoned DNS.

Performance and caching

  • Browsers cache PAC files, but refresh frequency varies. Use appropriate cache headers when serving PAC files.
  • Complex PAC logic (heavy DNS resolves, loops) can slow down request resolution. Keep FindProxyForURL efficient.
  • Prefer simple pattern matching with shExpMatch and dnsDomainIs over frequent dnsResolve calls.

Deployment tips

  • Host PAC on a reliable, fast server (HTTPS preferred).
  • Use versioned filenames or query strings to force client refresh after updates (e.g., proxy.pac?v=20250901).
  • Test on all target client platforms (Windows group policy, macOS network settings, Linux desktop environments, mobile browsers) because behavior can differ.
  • For managed environments, deploy via:
    • WPAD (Web Proxy Auto-Discovery) — has security considerations (risk of rogue WPAD servers).
    • Group Policy (Windows) to set PAC URL.
    • Mobile device management (MDM) solutions for iOS/Android.

Debugging tips

  • Simplify: Reduce rules to a minimal case that reproduces the issue.
  • Add logging via temporary modifications: e.g., return distinct proxy strings for branches and observe which is chosen.
  • Use pacparser to run unit tests against a list of URLs/hosts.
  • Check HTTP response headers for caching and MIME type (should be application/x-ns-proxy-autoconfig or text/plain).
  • Confirm PAC file URL is reachable and served with correct headers and status.

Common pitfalls

  • Relying on DNS resolution ordering — dnsResolve may block or fail.
  • Assuming consistent behavior across browsers/OSes — test widely.
  • Using long-running or blocking calls (e.g., lots of DNS lookups) inside FindProxyForURL.
  • Exposing PAC file over HTTP (man-in-the-middle risk).
  • Improper MIME type causing some clients to ignore the PAC.

Advanced topics (brief)

  • Generating PAC files dynamically server-side based on user, location, or device.
  • Integrating PAC with PAC-over-HTTPS (proxy auto-config delivered via HTTPS APIs).
  • Combining PAC with SD-WAN or split-tunnel VPN logic.
  • Using pacparser in CI to validate PAC changes before deployment.

Example full PAC file (comprehensive)

function FindProxyForURL(url, host) {   // local hostnames (no dots) and .local TLD   if (host.indexOf(".") == -1 || shExpMatch(host, "*.local")) return "DIRECT";   // Internal networks   if (dnsDomainIs(host, ".internal.example.com")) return "DIRECT";   if (isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0")) return "DIRECT";   // Special staging hosts   if (shExpMatch(host, "*.staging.example.com")) return "PROXY staging-proxy.example.com:8080";   // Default with failover   return "PROXY proxy1.example.com:3128; PROXY proxy2.example.com:3128; DIRECT"; } 

Conclusion

PAC files are a lightweight, flexible way to control proxy selection per request. For developers, mastering PAC scripting improves debugging, testing, and deployment of network routing rules. Keep PAC logic simple and fast, secure the PAC file distribution, and test across platforms to ensure consistent behavior.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *