Puppeteer "Navigation timeout of 30000 ms exceeded" in CI
page.goto and waitForNavigation default to a 30 second budget and a load condition such as networkidle. If the app is slow in CI, or the wait condition (like networkidle0) never settles, Puppeteer throws "Navigation timeout of 30000 ms exceeded".
What this error means
A test fails with "TimeoutError: Navigation timeout of 30000 ms exceeded" at a page.goto or page.waitForNavigation call, often on a runner slower than the developer machine.
TimeoutError: Navigation timeout of 30000 ms exceeded
at new Waiter (.../puppeteer/lib/cjs/puppeteer/common/LifecycleWatcher.js)
at Page.goto (.../puppeteer/lib/cjs/puppeteer/common/Page.js)Common causes
The app responded slower than 30 seconds
A cold or contended backend in CI made the page load exceed the default navigation timeout.
The waitUntil condition never settled
networkidle0 waits for zero in-flight requests; a page with long-polling or analytics beacons never reaches that state.
How to fix it
Raise the timeout and use a reachable waitUntil
- Increase the navigation timeout for CI.
- Use
domcontentloadedorloadinstead ofnetworkidle0when background requests never stop. - Re-run so navigation resolves within budget.
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60000 });Wait for the app to be ready first
Health-check the server before navigating so the first load is not racing a cold start.
- run: curl --retry 10 --retry-connrefused http://localhost:3000/healthzHow to prevent it
- Set CI navigation timeouts above the local default.
- Avoid networkidle0 on pages with continuous background traffic.
- Health-check the app before the first navigation.