pa11y error unable to load url connection timeout
Fixes pa11y unable-to-load-URL errors by triaging the network path from the scan environment. Use it when pa11y cannot reach the target URL at all. Not for pages that load but time out mid-scan, which is the page-load timeout failure.
pa11y error unable to load url connection timeout - how to fix it
TL;DR
Verify the URL is reachable from the scan environment: curl it from the same machine or container, check DNS and proxy settings, then pass the reachable URL to pa11y. Nine times out of ten the scanner cannot reach the host at all. One line of why: pa11y wraps Chromium network errors, and unable to load URL with a connection timeout means the browser never got a single byte.
The error, verbatim
Error: Unable to load URL: connect timed out
url: https://staging.example.com/app
Fix it step by step
Step 1: Reproduce the network failure
curl -sS -o /dev/null -w '%{http_code}\n' --max-time 20 https://staging.example.com/appExpected: curl also times out or fails, proving the scanner is not the problem.
Step 2: Check DNS resolution
node -e "require('dns').lookup('staging.example.com', function(e,a){console.log(e?e.message:a)})"Expected: Shows whether the hostname resolves in the scan environment.
Step 3: Check proxy requirements
env | rg -i 'proxy' | sed 's/=.*/=.../'Expected: Reveals proxy env vars; CI containers often need a proxy pa11y does not inherit.
Step 4: Scan the reachable URL
npx pa11y https://staging.example.com/app --reporter cli | tail -3Expected: Scan starts and reports violations once the URL is reachable.
Step 5: Re-run twice to rule out flakes
npx pa11y https://example.com/ | tail -2Expected: Two consecutive clean runs before calling it fixed; scan tools flake under load, so one green run is not proof.
When to use this skill
- The scan tool itself fails or crashes instead of reporting violations
- Your a11y CI step errors out before any rule results appear
- You run this tooling (pa11y, lighthouse, cypress-axe, axe-playwright) in automation
When NOT to use this skill
- The tool runs fine and reports real violations, use the rule-specific skills instead
- The failure is in your app code, not the scanner
Compatibility
pa11y 6.x / pa11y-ci 3.x. The fix is environmental: DNS, proxy, firewall, or VPN. Pin the tool version in the lockfile so scans stay reproducible across machines.
Variant phrasings
pa11y unable to load url
Same error, same network triage.
pa11y connect timed out staging
The classic: staging is VPN-only and CI has no VPN route.
same failure locally and in CI
Scan tool failures are environmental; a fix that works on a laptop must also be verified under CI conditions.
Why it happens
Pa11y runs Chromium, which uses the system network stack of wherever pa11y runs. Staging URLs behind VPNs, DNS that only resolves on the office network, and CI containers without proxy env vars all produce the same unable to load URL error. The error message does not distinguish DNS failure from TCP timeout from TLS failure, so triage with curl first to see which layer is broken. Scan tool failures are environmental more often than not: memory, network, certificates, and browser state. When a fix works locally, verify it under CI conditions too, because CI runners are slower, more locked down, and run things in parallel.
Edge cases
- If the site needs client certificates or VPN, run pa11y where a browser can actually reach it, not in a locked-down CI container.
- HTTP basic auth on staging needs --headers or a config file, a 401 is not a timeout but looks similar at first glance.
- IPv6-only CI networks failing to reach IPv4 hosts produce timeouts, check with curl -4 vs curl -6.
- Record the working flags in CI config or a runbook; the fix evaporates if it only lives in one person's shell history.
Provenance
Resolved from the public thread: https://vectle.com/posts/pstvH1QDjomEdJsQ6dGyaLxQ
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.