Debug Puppeteer by first identifying whether the failure is in your Node.js code, in code running inside the page, or in Chrome and its DevTools connection. Then make the browser observable: run it visibly, slow operations, forward page console messages, or capture browser and protocol output. The right fix depends on the symptom—launch errors, selector timeouts, and slow execution have different causes.
Start by locating the failing layer
A Puppeteer script crosses three boundaries: Node.js controls the browser, page JavaScript runs inside the site, and Chrome communicates with Node through the DevTools protocol. A failure at one boundary can look like a problem at another. Reproduce it and note the exact operation and error before changing launch flags or increasing timeouts.
As an Amazon Associate I earn from qualifying purchases.
- Node.js layer: Your script may have a logic error, an unhandled promise, or a wait that never completes.
- Page layer: The page may not have loaded the expected content, or its JavaScript may have thrown an error.
- Browser/protocol layer: Chrome may fail to launch, lack system dependencies, or stop responding to Puppeteer.
Puppeteer’s debugging guide recommends making Chrome visible or slowing operations first, then choosing diagnostics for the layer that owns the evidence. The guide is under the /next/ documentation path and may change before a stable release.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Make Puppeteer’s behavior observable
Show the browser and slow actions
For a local reproduction, launch in headed mode and add a delay between Puppeteer operations. This makes navigation, clicks, and page transitions easier to inspect:
#1 Best Overall
const browser = await puppeteer.launch({
headless: false,
slowMo: 100
});
Use the options supported by your installed Puppeteer version. A visible browser is useful for diagnosis, but it is not usually suitable for a headless server job.
Forward page console messages
Page errors and console output do not automatically appear as ordinary Node.js logs. Attach listeners before navigation so you do not miss messages produced during startup:
page.on('console', message => {
console.log(`PAGE ${message.type()}: ${message.text()}`);
});
page.on('pageerror', error => {
console.error('PAGE ERROR:', error);
});
If the page reports that a script failed or an expected value is missing, investigate the page’s own state before adjusting Puppeteer waits.
Use DevTools and the Node inspector
For interactive page-side debugging, open Chrome DevTools and place a debugger statement in the page code you need to inspect. For Node.js code, start the script with node --inspect-brk your-script.js and use the Node inspector. Puppeteer’s guide also describes inspecting the browser through chrome://inspect/#devices.
Capture browser and protocol output carefully
Set dumpio: true in launch options to forward the browser process’s standard output and error to the Node.js process. When the browser seems connected but protocol communication is stuck, enable Puppeteer protocol logging:
Rank #2
NODE_DEBUG="puppeteer:*" node your-script.js
Protocol logs can contain sensitive information. Review and redact them before sharing; do not publish raw logs that may expose page data, credentials, or other private values.
Why is Puppeteer not launching Chrome?
First record the installed Puppeteer version, browser build or channel, operating system, and launch options. Puppeteer guarantees compatibility with its bundled browser; using a system browser or alternate channel is at your own risk, according to the LaunchOptions reference. If the problem began after upgrading, verify that pairing before trying unrelated flags.
“Could not find expected browser locally”
Check where Puppeteer installed its browser and which home directory the process uses. The troubleshooting guide says that from Puppeteer v19, browser downloads are stored under ~/.cache/puppeteer, using the home directory. A service account, container, or runtime with a different or unavailable home directory may therefore look in the wrong place. If the default location is unsuitable, configure PUPPETEER_CACHE_DIR and ensure the browser is installed in the location used at runtime.
Missing Linux shared libraries
Chrome may exist but fail to start because the Linux image is missing shared-library dependencies. On Linux, inspect the browser binary with:
ldd /path/to/chrome | grep not
Replace the path with the Chrome executable used by your installation. Install the missing dependencies for your distribution and verify the package names against the current requirements: the troubleshooting guide gives Debian and CentOS examples, but there is no single package list that applies to every Linux distribution.
Sandbox and AppArmor failures
Keep sandbox restrictions separate from library problems. The troubleshooting guide notes that Ubuntu 23.10 and later may apply an AppArmor profile that prevents Chrome for Testing from using user namespaces, producing an error such as No usable sandbox!. Check the documented Chromium AppArmor restrictions and use an environment-appropriate remedy.
Puppeteer’s warning is explicit: “Running without a sandbox is strongly discouraged.” Treat --no-sandbox as a security-relevant workaround, not a routine launch fix. Prefer preserving the browser sandbox and correcting the host or container configuration.
Profile directory is not writable
Puppeteer normally creates a temporary Chrome profile. If you set userDataDir yourself, confirm that the directory exists or can be created, is writable, and is owned or accessible by the same account that runs Chrome. A mounted read-only or incorrectly owned profile directory can prevent launch or cause confusing profile errors.
Docker process and privilege checks
In Docker, check the container’s privileges and filesystem permissions independently from Puppeteer’s JavaScript options. If Chrome child processes remain as zombies after jobs finish, the troubleshooting guide notes that dumb-init may help manage processes. These are container-specific checks, not universal Puppeteer requirements.
Alpine-specific caveats
The troubleshooting documentation says Chrome does not support Alpine out of the box; compatible system dependencies must be installed and the image tested. It also flags timeout issues with the Chromium version in Alpine 3.20. Keep that warning specific to the documented distribution and version rather than assuming it applies to every Alpine release or Chromium build.
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #4
Why does waitForSelector time out?
A timeout means Puppeteer did not observe the requested selector or condition within the allotted time. Before extending the timeout, check whether the selector is correct, whether navigation reached the intended page state, and whether the element is inside a frame or otherwise unavailable in the context you queried.
Prefer Locators for interactions
Puppeteer’s page interactions guide recommends Locators for selecting and interacting with elements. They wait for the element and relevant action preconditions, such as whether an interaction can proceed. A Locator can have a per-locator timeout; Puppeteer throws a TimeoutError if the element is not found or the preconditions are not met in time.
Use waitForSelector when you need an explicit wait
waitForSelector is a lower-level option. The API reference says it waits for a selector and throws if it does not appear before the timeout. It does not automatically retry a later action after a failure. If it returns an ElementHandle, dispose of that handle when finished to avoid retaining resources:
const handle = await page.waitForSelector('.result', { timeout: 10_000 });
try {
// Use the element here.
} finally {
await handle?.dispose();
}
Do not treat a larger timeout as a fix until you have verified that the selector, page state, and wait condition match what the page actually does.
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 minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallWhy is Puppeteer slow on Google Cloud Run?
This can be a Cloud Run CPU-allocation issue rather than a general Puppeteer performance problem. Puppeteer’s troubleshooting guide explains that Cloud Run disables CPU by default after an HTTP response has been written. If you send the response and only then launch Chrome or start capture work, that work may appear unusually slow.
Best Value
- Used Book in Good Condition
For work that belongs to the request, launch Puppeteer and complete the browser operation before writing the response. For genuine background work, consult Cloud Run’s configuration for enabling always-allocated CPU. This behavior and remedy are specific to that deployment condition; they should not be applied as general advice for other hosting platforms.
Fixes to avoid applying blindly
- Do not change several launch flags at once. Make one change, reproduce the same failure, and compare the output so you can identify which condition mattered.
- Do not assume every launch failure is a sandbox failure. Cache paths, shared libraries, profile permissions, and browser compatibility can produce separate symptoms.
- Do not silence a selector timeout by only increasing its duration. Confirm the page reached the expected state and that the selector and interaction are appropriate.
- Do not assume Cloud Run guidance applies elsewhere. Its post-response CPU behavior is a platform-specific case.
- Do not share unreviewed diagnostics. Browser and protocol logs may expose sensitive data.
Or skip the browser setup
If your goal is to get a website screenshot rather than debug Puppeteer itself, ScreenshotNeo is a website screenshot API and MCP server for developers. A single GET request returns a PNG, JPEG, WebP, or PDF. For example, this cURL request saves a WebP screenshot; see the ScreenshotNeo API documentation for parameters and response details:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each of those steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsSign up for ScreenshotNeo’s free plan to try 1,000 screenshots a month with no card.
Frequently Asked Questions
Which Puppeteer version should I use when debugging?
Use the version installed by your project and record it alongside the browser build or channel, operating system, and launch options. Check the current Puppeteer documentation for version-specific guidance.
Can I use Puppeteer on Alpine Linux?
The Puppeteer troubleshooting guide says Chrome is not supported on Alpine out of the box; compatible dependencies must be installed and the image tested. Its timeout note specifically calls out Chromium in Alpine 3.20.
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.




