libnyanpasu/clash-nyanpasu · error

failed to download PAC script: {}

Error message

failed to download PAC script: {}

What it means

download_pac_script uses a reqwest client to GET the PAC URL; this error is thrown when the request itself fails at the transport level (DNS resolution failure, connection refused/timeout, TLS error). It is logged per-attempt and stored as last_error, retried up to PAC_MAX_RETRIES times with PAC_RETRY_DELAY between attempts.

Source

Thrown at backend/tauri/src/core/pac.rs:58

                            Ok(content) => return Ok(content),
                            Err(e) => {
                                let err =
                                    anyhow::anyhow!("failed to read PAC script content: {}", e);
                                log::warn!(target: "app", "Attempt {}/{} failed: {}", attempt, PAC_MAX_RETRIES, err);
                                last_error = Some(err);
                            }
                        }
                    } else {
                        let err = anyhow::anyhow!(
                            "failed to download PAC script, status: {}",
                            response.status()
                        );
                        log::warn!(target: "app", "Attempt {}/{} failed: {}", attempt, PAC_MAX_RETRIES, err);
                        last_error = Some(err);
                    }
                }
                Err(e) => {
                    let err = anyhow::anyhow!("failed to download PAC script: {}", e);
                    log::warn!(target: "app", "Attempt {}/{} failed: {}", attempt, PAC_MAX_RETRIES, err);
                    last_error = Some(err);
                }
            }

            // Wait before retrying (except on last attempt)
            if attempt < PAC_MAX_RETRIES {
                tokio::time::sleep(Duration::from_secs(PAC_RETRY_DELAY)).await;
            }
        }

        Err(last_error.unwrap_or_else(|| {
            anyhow::anyhow!(
                "failed to download PAC script after {} attempts",
                PAC_MAX_RETRIES
            )
        }))
    }

View on GitHub (pinned to f7dbce2997)

Solutions

  1. Check network connectivity and DNS resolution of the PAC URL host (ping/nslookup)
  2. Verify the PAC URL scheme and host are correct (http vs https, no typos)
  3. Check for expired TLS certificates if using HTTPS (curl -v the URL)
  4. Confirm firewall/VPN/corporate proxy is not blocking the connection
  5. Rely on the fallback: update_pac() falls back to direct proxy when PAC download fails

Example fix

// before
pac_url = "https://pac.internal.lan/proxy.pac"
// after
pac_url = "https://pac.example.com/proxy.pac" // reachable, DNS-resolvable host
Defensive patterns

Strategy: retry

Validate before calling

fn pac_host_resolvable(url: &str) -> bool {
    url::Url::parse(url).ok()
        .and_then(|u| u.host_str().map(|h| std::net::ToSocketAddrs::to_socket_addrs(&(h, u.port_or_known_default())).is_ok()))
        .unwrap_or(false)
}

Try / catch

match download_pac_script().await {
    Ok(script) => install(script),
    Err(e) if e.to_string().contains("failed to download PAC script") => {
        log::warn!("transport failure ({e}); checking connectivity before retry");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling download_pac_script when reqwest's .send() returns Err — hostname not resolvable, server unreachable, connection reset, TLS handshake failure, or request timeout.

Common situations: PAC URL uses a hostname that no longer resolves; firewall blocks outbound access; server offline; TLS certificate expired or untrusted; system has no network connectivity at startup.

Related errors


AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08). Data as JSON: /api/errors/85681869f620bec2. Report an issue: GitHub.