Skip to content
Latchkey

pa11y-ci "Timed out" / page did not load in CI

pa11y-ci launches a headless browser to load each URL; if the page never finished loading within the timeout, or the server was not up, pa11y throws instead of reporting accessibility results.

What this error means

pa11y-ci prints "Error: Pa11y timed out (30000ms)" or "net::ERR_CONNECTION_REFUSED" for a URL, and the run fails before any accessibility rules are evaluated.

pa11y-ci
Running Pa11y on 1 URLs:
Error: Pa11y timed out (30000ms)
    at Timeout._onTimeout (.../node_modules/pa11y/lib/pa11y.js:...)
 x http://localhost:3000/ - Failed to run

Common causes

The app server was not ready when pa11y ran

pa11y started before the dev/preview server finished booting, so the connection was refused or the page never loaded.

Dynamic content was not waited for

A single-page app renders after load; without a wait for a selector or network idle, pa11y scans an empty shell or times out.

How to fix it

Wait for the server before scanning

  1. Use a readiness wait (wait-on) so pa11y only runs once the URL responds.
  2. Increase the pa11y timeout for slow-loading pages.
  3. Re-run pa11y-ci once the server is confirmed up.
Terminal
npx wait-on http://localhost:3000 && pa11y-ci

Wait for content to render before the scan

Configure a waitUntil and a selector wait so pa11y scans the hydrated page, not an empty shell.

.pa11yci.json
{
  "defaults": {
    "timeout": 60000,
    "chromeLaunchConfig": { "args": ["--no-sandbox"] },
    "waitUntil": "networkidle0"
  }
}

How to prevent it

  • Gate pa11y behind a server readiness check like wait-on.
  • Wait for a stable selector or network idle before scanning SPAs.
  • Set timeouts that reflect real page load time in CI.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →