What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Puppeteer’s “Navigation Timeout of 30000 ms Exceeded” error means the navigation did not satisfy its configured waitUntil condition before the timeout—30,000 milliseconds by default. It does not, on its own, tell you whether the page is slow, an external resource is hanging, or the chosen readiness condition is too strict. Start by matching the wait condition to what your code actually needs; increase the timeout only if that work is legitimately expected to take longer.
What the 30-second navigation timeout means
Puppeteer waits for a navigation lifecycle condition before treating a navigation-related operation as complete. The default maximum wait is 30,000 milliseconds. The default waitUntil condition is load; if you provide an array of lifecycle conditions, all of them must occur for the wait to succeed. The error means that the selected condition did not complete in time. It does not identify the underlying cause.
The operation may be page.goto(), page.reload(), page.setContent(), page.waitForNavigation(), or another method affected by the page’s default navigation timeout. Puppeteer’s current Page API reference describes that setting as the maximum navigation time in milliseconds. Check the operation named in the stack trace and the options passed to it before changing a timeout globally.
Timeout is not the same as an HTTP error
A navigation timeout is about the wait condition not completing before the deadline. It is a separate issue from the HTTP status returned for a page. Current Page API documentation says headless shell navigation does not throw merely because it receives a valid status such as 404 or 500; inspect the navigation response status separately. A 404 response can arrive promptly, while a page that returns a successful status can still fail to meet a lifecycle wait condition.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problems#1 Best Overall
Diagnose the specific operation before changing settings
- Identify the operation. Find the call named in the error or stack trace: for example,
goto,setContent, orwaitForNavigation. Record the URL or content being loaded and any timeout orwaitUntiloptions set at the call site. - Log what the navigation returned. Capture the response status when one is available, the response URL, the page’s final URL, and the chosen lifecycle condition. A navigation can redirect, and the response may be
nullin cases where there is no standard response to inspect, so guard against that. - Compare local and deployed runs. If the same operation succeeds locally but fails in a server or container, check whether the runtime can reach the same hosts. DNS, TLS, proxy, firewall, and outbound-network differences are useful leads; the timeout alone does not prove which one is responsible.
- Look for work that is not essential. Third-party scripts, fonts, analytics, ads, or API requests may delay the condition you selected. Determine whether your task requires them, whether they are reachable in the deployed environment, and whether the condition is waiting for more than the task needs.
A small amount of context in your logs makes the next choice much safer than simply disabling the timeout. For example, log the URL, the response status if present, and the wait condition alongside the error. Do not treat the status as proof that the rendered page contains the data your script needs; use a readiness signal for that.
Choose a readiness condition that matches the job
Use domcontentloaded when the initial document is enough
If you only need the initial DOM—for example, to inspect markup that is available as soon as the document is parsed—domcontentloaded may be enough. It avoids waiting for the full load condition, which can be delayed by resources that are not relevant to your task. It is not a guarantee that a client-side application has finished rendering its data or that images are ready for a screenshot.
const response = await page.goto(url, {
waitUntil: 'domcontentloaded',
timeout: 60_000,
});
console.log({
requestedUrl: url,
responseUrl: response?.url() ?? null,
status: response?.status() ?? null,
finalUrl: page.url(),
waitUntil: 'domcontentloaded',
});
This example uses a 60-second per-call limit as an illustration of a bounded increase, not as a universal recommendation. Choose a deadline appropriate for your own workload.
Wait for the application signal when the page is dynamic
For a client-rendered page, navigation completing does not necessarily mean the content you need is ready. Navigate with a reasonable lifecycle condition, then wait for a specific element or application-ready marker. The selector should indicate the data or state your next operation depends on, not merely an element that appears before the work is finished.
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
await page.goto(url, { waitUntil: 'domcontentloaded' });
await page.waitForSelector('#report-ready', { timeout: 15_000 });
const report = await page.$eval('#report-ready', element => element.textContent);
Give the selector wait its own finite timeout so that a missing or renamed marker produces a bounded failure rather than leaving the task stuck. If you are capturing a screenshot or PDF, identify which assets must actually be present and wait for those assets or a page-specific ready signal rather than assuming all network activity will stop.
Use load only when the full load event matters
load is Puppeteer’s default lifecycle condition. Keep it when your task genuinely depends on the page reaching that condition. If it is not completing, inspect the resources the page is trying to load before relaxing the condition. Avoid combining lifecycle events as if an array meant “any one is sufficient”: Puppeteer documents that every event in the array must fire.
Increase the timeout when a slow navigation is expected
If the page needs more time for a legitimate reason and you still need the same lifecycle condition, increase the limit. A per-call timeout changes one operation; page.setDefaultNavigationTimeout() changes the default for navigation-related methods on that page, including back, forward, goto, reload, setContent, and waitForNavigation.
Set a limit for one navigation
await page.goto(url, {
waitUntil: 'domcontentloaded',
timeout: 60_000,
});
This keeps the change local to the call. Prefer it when only one destination or operation is slower than usual.
Rank #3
Set the page’s default navigation limit
page.setDefaultNavigationTimeout(60_000);
await page.goto(url, { waitUntil: 'load' });
Use a page-wide default only when the longer limit is appropriate for the navigation operations that share that page. It is not the same as changing every kind of wait timeout, and it does not make a page load faster. If a page is consistently slow because a resource is unreachable, a larger limit may only make failures take longer to surface.
Use timeout: 0 only with another deadline
Puppeteer’s WaitForOptions reference says that passing 0 disables the wait timeout. That removes Puppeteer’s bound for the relevant wait; it does not fix a stalled navigation. Do this only for a controlled operation with an independent abort signal or application-level deadline, so a broken resource cannot hold a worker indefinitely. In production automation, a finite limit plus explicit error handling is usually easier to recover from than an unbounded wait.
Fix click-triggered navigation races
A click that starts navigation can race with a separately awaited waitForNavigation(). If the click triggers navigation before the wait has been registered, the wait may miss the event. Start both operations together with Promise.all, using the documented pattern:
const [response] = await Promise.all([
page.waitForNavigation({ waitUntil: 'domcontentloaded' }),
page.click('a.next'),
]);
console.log({
status: response?.status() ?? null,
finalUrl: page.url(),
});
This coordinates the wait and click; it does not guarantee that the destination application has finished its own asynchronous rendering. If the next step needs a rendered result, wait for its selector or ready signal after navigation as well.
Rank #4
- 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
Investigate external resources when setContent() or PDF output hangs
page.setContent() can wait for a lifecycle condition too, so supplied HTML with external dependencies can produce a navigation timeout even though the content is not loaded with page.goto(). In Puppeteer GitHub issue #12077, opened on March 13, 2024, a report involving Puppeteer 21.9.0 and Node 16.20.0 on Linux described page.setContent(html, {waitUntil: 'domcontentloaded'}) followed by page.pdf(); the reporter said removing external resources from the HTML allowed PDF generation. That report is an example of a possible cause, not proof that external resources explain every similar timeout.
For your own HTML, inspect script, stylesheet, font, and image URLs that point outside the document. Confirm the runtime can reach them and decide whether the output actually needs them. If the document can be rendered without a dependency, remove or inline it; if it is required, wait for the particular content you need and retain a finite deadline. A PDF failure after setContent() should be diagnosed at the wait that timed out rather than attributed automatically to PDF generation.
Troubleshoot by symptom
| Symptom | Likely area to inspect | Next action |
|---|---|---|
goto() times out, but the page is usable in a browser |
The selected waitUntil condition or resources that remain active. |
Try the least strict condition that meets the task, then wait for a required selector or app-ready signal. |
| It works locally but times out in CI or a container | Differences in DNS, TLS, proxy, firewall, or outbound network access. | Compare whether the deployed runtime can reach the page and its external dependencies. |
setContent() hangs when HTML includes remote assets |
External scripts, stylesheets, fonts, images, or other requests. | Test whether the output needs each dependency; remove unnecessary resources or wait for the required result explicitly. |
| A click succeeds but the following navigation wait times out | A race between the click and a separately started waitForNavigation(). |
Register both through Promise.all as shown above. |
| The error persists after increasing the limit | The operation may be waiting for the wrong condition, or a required resource may never complete. | Re-check the lifecycle condition and resource reachability instead of continuing to raise the limit. |
| A response has status 404 or 500 | HTTP status handling, not necessarily a navigation timeout. | Inspect the response status separately and handle the returned page according to your task. |
Performance, reliability, and cost considerations
Navigation waits affect throughput: a longer deadline gives a slow page more time, but a stalled request can also keep a worker occupied longer before it fails. A shorter, task-appropriate lifecycle wait followed by a targeted selector wait can avoid waiting on unrelated work. Keep deadlines finite, log the operation and response context, and handle timeouts as expected failures if your automation runs across many URLs.
For screenshot or PDF jobs, distinguish a browser navigation problem from the capture requirement. A page may be navigable before all screenshot-critical assets are ready, while waiting for every network request may be stricter than needed. Define the visual or document state you require and coordinate your waits around that state. Do not interpret a timeout as evidence that a destination is offline, nor interpret a longer timeout as evidence that a result is complete.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Best Value
Or skip the browser setup
If your goal is simply to capture a website rather than control Puppeteer itself, ScreenshotNeo provides a screenshot API and MCP server. It does not change Puppeteer’s timeout behavior or diagnose your Puppeteer script; it is an alternative when you want the screenshot output without managing a browser capture flow. Its clean-shot steps can accept cookie or consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets, and each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing; response headers identify the page verdict and whether the request was billed. AI agents can use its MCP server tools, including take_screenshot, get_page_info, and capture_pdf.
Make one GET request for a screenshot; replace the example URL with the page you want and supply your API key. See the ScreenshotNeo API documentation for request options and response details.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
ScreenshotNeo’s Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Sign up free for 1,000 screenshots a month—no card required.
Frequently Asked Questions
Does this error mean the website is down?
No. The timeout only establishes that Puppeteer did not observe the selected lifecycle condition before the configured deadline. Check the response and the resources your page needs to distinguish a slow or blocked dependency from an unavailable destination.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Should I always replace load with networkidle?
No. Choose a condition based on the task. If your requirement is a particular rendered result, a page-specific selector or ready signal is more direct than waiting for general network activity to stop.
Quick Recap
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.

