Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A timeout is not a diagnosis. First identify the awaited operation that rejected—navigation, a selector or locator, a request or response, an action, or the enclosing test. Then wait for the state your task actually requires and change the narrowest applicable timeout. A larger number cannot repair a wrong URL, missing selector, navigation race, incompatible browser, or page that never reaches the chosen event.

1. Find the operation that actually timed out

Read the complete stack trace and locate the rejected call. The text Navigation timeout of 30000 ms exceeded is commonly associated with navigation, but the wording alone is not enough to identify every timeout in a Puppeteer or Pyppeteer program.

  • page.goto(), reload(), goBack(), goForward(), or waitForNavigation(): investigate navigation timing and lifecycle assumptions.
  • waitForSelector() or a locator: check the selector, frame, shadow root, visibility, and application state.
  • waitForResponse() or waitForRequest(): verify the URL pattern, method, and whether the request is expected at all.
  • A test-runner or job deadline: the browser wait may be healthy while the enclosing test or worker has already exceeded its own limit.

Before changing a timeout, log the input URL and the condition being awaited. Ask whether authentication, consent, a redirect, a different route, or an iframe changes what the script can see. If the event will never occur, waiting longer only delays the same failure.

2. Puppeteer: use the timeout that matches the operation

Current Puppeteer Page documentation separates navigation defaults from general waits. page.setDefaultNavigationTimeout() applies to goBack, goForward, goto, reload, setContent, and waitForNavigation. page.setDefaultTimeout() changes the general default used by other waits and actions. A waitForSelector call has a documented 30,000-millisecond default and accepts a per-call timeout; setting that value to 0 disables that selector wait’s timeout.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Set a one-off navigation limit

await page.goto(url, {
  waitUntil: 'domcontentloaded',
  timeout: 60_000,
});

await page.waitForSelector('[data-ready="true"]', {
  visible: true,
  timeout: 20_000,
});

The values are examples, not universal requirements. Use domcontentloaded only when the task does not need every image, stylesheet, font, or other resource to finish. If your task needs a particular application state, follow navigation with a verified selector, URL, response, or locator condition.

Change a page-level default deliberately

page.setDefaultNavigationTimeout(60_000);
page.setDefaultTimeout(20_000);

Keep these settings near the page setup and document why they are needed. A navigation default does not automatically change every selector or action wait, and a general default does not replace a test-runner deadline. Avoid setting a broad default to zero merely to make a hang appear fixed.

3. Pyppeteer: verify the installed version first

The published Pyppeteer 0.0.25 reference documents a 30-second default for goto() navigation and supports a per-call timeout plus setDefaultNavigationTimeout(). It also describes a 30-second selector-wait default. That reference is old, so check the package installed in your environment and confirm its accepted option names and behavior rather than assuming every current Puppeteer API has an equivalent.

Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

Use a scoped timeout with the documented argument style

await page.goto(
    url,
    {
        "waitUntil": "domcontentloaded",
        "timeout": 60_000,
    },
)

await page.waitForSelector(
    '[data-ready="true"]',
    {"timeout": 20_000},
)

Pyppeteer is documented as working best with its bundled Chromium version. If a timeout appears with a launch, disconnect, or protocol error, investigate browser and package compatibility as a separate problem; increasing a page wait will not repair a disconnected or incompatible browser.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

4. Wait for the state your script needs

load, domcontentloaded, network-idle conditions, and an application-specific element represent different states. Choose among them from the task requirement, not habit. A server-rendered page may be usable at DOM content loaded; a client-rendered dashboard may require a known ready element or response. Do not replace a verified condition with an arbitrary sleep.

Use locators for interaction state

Puppeteer locators automatically wait for an element to be present and in the appropriate state for an action, and locator timeouts can be scoped to that operation. A selector wait can also require visibility or hidden state. If it expires, inspect the current URL and DOM, confirm the selector spelling, and check whether the element is inside another frame or a shadow root.

Rank #3
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

Coordinate clicks that cause navigation

A click-triggered navigation can race if the click is awaited separately before registering waitForNavigation(). Coordinate both promises:

await Promise.all([
  page.waitForNavigation({waitUntil: 'domcontentloaded'}),
  page.click('a.next'),
]);

Use this pattern only when the click is expected to cause a real document navigation. For client-side routing or an in-page update, wait for the resulting URL, selector, locator state, or response instead. Confirm the syntax supported by your installed framework version before porting the pattern to Pyppeteer.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

5. Diagnose by failure type

Navigation expires

  • Log the final URL and inspect redirects.
  • Confirm network access, authentication, proxy settings, and the intended route.
  • Reconsider waitUntil if the page keeps long-running requests open.
  • Check whether the script needs a document lifecycle event or a later application-ready state.

There is no single lifecycle condition that is correct for every site. Select the narrowest condition that proves your task can safely continue.

A selector or locator expires

  • Verify the selector against the current DOM, not the expected DOM.
  • Check the URL after redirects and whether login or consent changed the page.
  • Search the correct iframe and account for shadow-root boundaries.
  • Remove a visibility requirement only if hidden content is genuinely sufficient for the next operation.

A request or response wait expires

  • Confirm the exact endpoint, method, and URL pattern.
  • Register the wait before the action that emits the request.
  • Check whether the action uses a cache, service worker, or a different API route.

The browser disconnects or the test deadline expires

Treat a browser launch, protocol, or disconnect error as its own failure. Likewise, compare the browser wait with the test-runner’s overall deadline. Raising only the page timeout cannot extend a shorter enclosing deadline.

6. Choose the narrowest effective fix

What is awaited? Preferred control What to verify
One navigation Per-call timeout URL, redirects, and lifecycle condition
Several legitimate navigations setDefaultNavigationTimeout() Keep scope to the page and document the reason
One selector or locator Per-call or per-locator timeout Selector, frame, visibility, and application state
Many non-navigation waits setDefaultTimeout() Ensure actions do not inherit an unnecessarily long bound
Whole test or job Test-runner or worker deadline Leave enough time for all browser operations

A longer bound is justified when the event is valid but predictably slow. It is not a substitute for correcting a missing event, wrong selector, race, or broken browser. Disabling a timeout can turn a visible failure into an indefinitely stuck worker.

7. A repeatable troubleshooting checklist

  1. Copy the complete error and stack trace.
  2. Identify the exact awaited call that rejected.
  3. Log the URL, selector, frame, request pattern, and current page URL.
  4. Ask whether the awaited event should occur for this input.
  5. Check redirects, authentication, consent, visibility, and client-side rendering.
  6. Choose an application-specific state instead of an arbitrary delay.
  7. Apply a per-call timeout first; widen a page default only when several operations require it.
  8. Compare the browser timeout with the test or job deadline.
  9. Check the installed Puppeteer or Pyppeteer version and browser compatibility.
  10. Reproduce with the same URL and input, then retain diagnostics for the next failure.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

For a screenshot job, ScreenshotNeo provides a single HTTP request instead of requiring you to manage Chromium, navigation waits, and selector timing. Before capture it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo documentation for parameters and response details. The same endpoint supports PNG, JPEG, WebP, or PDF output, full-page capture with lazy images loaded, CSS-selector element capture, dark mode, device presets and custom viewports, retina scale, custom CSS and JavaScript, pre-capture clicks, hidden selectors, waits for selectors, delays or network idle, blocked ads or resources, custom headers, cookies, user agents and authorization, timezone and geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Common parameter names from other screenshot APIs also work, which can simplify migration.

Plans include 1,000 screenshots per month free with no card; paid plans start at $5 for 3,000 shots. Every feature is available on every plan. Create a free ScreenshotNeo account to try it.

8. Using ScreenshotNeo from Python or Node.js

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`ScreenshotNeo HTTP ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

Frequently Asked Questions

Should I set every Puppeteer timeout to zero?

No. A zero timeout removes the bound for that wait and can leave a worker stuck indefinitely. Use it only when an intentionally unbounded wait is appropriate and another watchdog exists.

Why does increasing navigation timeout not fix a missing element?

Navigation and selector waits have separate controls. If navigation completes but the application never renders the selector, inspect the URL, DOM, frame, visibility, and application state instead of changing the navigation limit.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Is Pyppeteer interchangeable with current Puppeteer?

No. The published Pyppeteer 0.0.25 reference is old. Check your installed package and browser versions and validate option names before adapting current Puppeteer examples.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.