ScreenshotNeo

BlogHow-to

Why Pyppeteer Stops Working When Opening the Browser and How to Fix It

Pyppeteer launch failures usually come from browser discovery, incompatible binaries, missing Linux libraries, or unwritable profiles. Diagnose each case step by step.

By the ScreenshotNeo team30 September 20267 min read

Why Pyppeteer Stops Working When Opening the Browser and How to Fix It

Short answer: if Pyppeteer stops at await launch(), treat it as a browser-process startup problem first. Check whether Chromium was downloaded and is executable, turn on browser stderr with dumpio=True, verify the executable path and browser version, then check Linux libraries and writable profile directories. Navigation timeouts that occur after a page opens belong to a different diagnostic path.

Pyppeteer can download Chromium on first use when it cannot find a browser. The project README describes a download of approximately 150 MB, although the size varies by release. You can also run pyppeteer-install explicitly. Pyppeteer’s API reference recommends its bundled Chromium for compatibility; separately installed Chrome or Chromium versions are not guaranteed to work.

1. Confirm that the failure is really at launch

Capture the complete traceback and identify the first failing await:

Separate browser launch failures from page navigation failures before changing configuration.
Separate browser launch failures from page navigation failures before changing configuration.
Where it fails Likely branch
await launch() Browser binary, executable permission, shared library, sandbox, profile, or process startup
await browser.newPage() Browser may have exited immediately, or the connection was lost
page.goto() or navigation DNS, TLS, proxy, page timeout, blocked request, or site behavior

Do not “fix” a navigation timeout by changing browser-installation settings. First prove which stage fails.

2. Reproduce with a minimal diagnostic script

Use a small script that exposes Chrome’s stdout and stderr and always closes the browser:

import asyncio
from pyppeteer import launch

async def main():
    browser = await launch(dumpio=True)
    try:
        page = await browser.newPage()
        print(await page.title())
    finally:
        await browser.close()

asyncio.run(main())

dumpio=True pipes browser-process output to your Python process. Save that output before changing several launch options at once. The launch flow and option are documented in the Pyppeteer repository and API reference.

3. Check Chromium installation and discovery

Let Pyppeteer install its bundled browser

python -m pip install --upgrade pyppeteer
pyppeteer-install

Run the install command as the same user and inside the same virtual environment or container that runs your application. Verify that the expected Chromium file exists and that the runtime user can execute it. A partial download, a failed first-use download, or a cache directory that is unavailable to the service account can all look like a launch failure.

Use an explicit executable path

If your deployment manages Chrome or Chromium separately, pass the path that exists on that machine:

import asyncio
from pyppeteer import launch

async def main():
    browser = await launch(
        executablePath="/absolute/path/to/chrome-or-chromium",
        dumpio=True,
    )
    try:
        page = await browser.newPage()
        await page.goto("https://example.com")
        print(await page.title())
    finally:
        await browser.close()

asyncio.run(main())

Do not copy a path from another operating system or image. Locate the binary in the target runtime and check its permissions. The executablePath option is part of Pyppeteer’s documented launch API.

4. Check browser-version compatibility

Pyppeteer works best with the Chromium revision it bundles. A system Chrome update can introduce a mismatch even when your Python code has not changed. Compare the installed browser version with the Pyppeteer release, then retry with the bundled browser as a controlled comparison. If the bundled browser launches and the system browser does not, the problem is compatibility or the system installation rather than your page code.

Choice Advantages Costs and risks
Bundled Chromium Version selected for Pyppeteer; predictable API pairing Initial download and cache management
System Chrome/Chromium Central security updates and image control You must maintain the path, dependencies, permissions, and version compatibility

5. Diagnose Linux shared-library failures

On Linux, Chrome can exit before Pyppeteer connects when a required .so library is missing. If stderr names a library, inspect dependencies on the actual browser binary:

ldd /absolute/path/to/chrome | grep not

An empty result means this command did not find unresolved libraries; it does not prove every runtime issue is solved. Install the matching packages for your distribution and image, then rerun the check. The related Puppeteer troubleshooting guide lists Debian/Ubuntu dependency examples and the ldd ... | grep not technique. Those package lists are Chromium guidance for the related JavaScript project, so verify names against your base image before applying them to Pyppeteer.

6. Check writable directories in containers and CI

A read-only filesystem or an unwritable home directory can prevent Chrome from creating its cache, configuration, or profile. Check the user running the process and the permissions of its home and temporary directories. When the error points to profile or filesystem access, provide writable XDG locations and an explicit writable user-data directory:

import asyncio
from pyppeteer import launch

async def main():
    browser = await launch(
        dumpio=True,
        userDataDir="/tmp/pyppeteer-profile",
    )
    try:
        page = await browser.newPage()
        print(await page.title())
    finally:
        await browser.close()

asyncio.run(main())

Use a directory that the service user can create and clean. The Puppeteer troubleshooting documentation also discusses writable XDG cache/config paths. Apply those environment changes only when the error and deployment restrictions indicate a permissions problem.

7. Treat sandbox errors as a specific case

Some CI or container environments report a sandbox initialization error. Do not add --no-sandbox as a generic remedy: disabling the browser sandbox changes security properties. First identify the exact sandbox error and decide whether the image can provide the required user namespace or sandbox configuration. If your deployment’s security policy explicitly permits the flag for that isolated workload, document the decision and scope it to that environment.

8. A repeatable troubleshooting checklist

  1. Confirm the exception occurs during launch(), not navigation.
  2. Run the minimal script with dumpio=True and save stderr.
  3. Confirm Pyppeteer is installed in the runtime environment that executes the job.
  4. Complete the bundled Chromium download with pyppeteer-install, or verify the cache and browser file.
  5. Check that the browser file is executable by the service user.
  6. Try an explicit, absolute executablePath when using a managed browser.
  7. Compare browser and Pyppeteer versions; retry with bundled Chromium.
  8. For missing .so errors, run ldd <browser> | grep not and install distribution-matching libraries.
  9. For profile or cache errors, provide writable directories and a writable userDataDir.
  10. Only investigate sandbox configuration when stderr identifies a sandbox failure.

9. Common errors, causes, and fixes

Symptom Probable cause Fix
“Browser is not downloaded” or missing executable First-use download did not complete or cache is absent Run pyppeteer-install in the runtime environment; verify the cache and permissions
“No such file or directory” for Chrome Wrong or machine-specific executable path Find the binary in the target image and pass an absolute executablePath
“Permission denied” Binary or profile is not accessible to the service user Fix execute permission and use writable cache/profile directories
stderr names a missing .so Linux shared-library dependency is absent Inspect with ldd; install the matching packages for the base distribution
Browser opens then disconnects Chrome crashed, ran out of resources, or could not write its profile Read dumpio output, check memory/filesystem limits, and isolate a writable profile
Works locally, fails in CI Different browser path, user, libraries, sandbox, or read-only filesystem Print the runtime identity and path, inspect dependencies, and compare the CI image with local versions
Launch succeeds but goto() times out Network, DNS, proxy, TLS, or target-site behavior Debug navigation separately; do not reinstall Chromium until launch itself is reproduced as failing

10. Performance, reliability, and cost considerations

  • Startup cost: the first bundled-browser download is large (the README says approximately 150 MB) and cold launches are slower than reusing a browser process.
  • Reuse carefully: keeping one browser alive can reduce startup overhead, but isolate pages and restart the process after crashes or suspected leaks.
  • Cache deliberately: preinstall Chromium in a controlled image when outbound downloads are unavailable, and make the cache readable by the runtime user.
  • Pin the environment: record the Pyppeteer version, browser revision, base image, and launch arguments so CI failures are reproducible.
  • Resource limits: container CPU, memory, /dev/shm, and process limits can cause a browser to exit even when dependencies are present.
  • Security: preserve the sandbox whenever the environment supports it; treat any exception as a documented deployment decision.

11. Should you migrate from Pyppeteer?

The current Pyppeteer repository says the project is unmaintained and suggests considering playwright-python. That is a maintenance decision, not proof that a particular launch error will disappear. A migration still requires checking browser versions, Linux libraries, writable directories, sandbox behavior, and CI constraints.

12. Or skip the browser setup

If your goal is a clean website image rather than browser automation, ScreenshotNeo accepts one GET request and returns PNG, JPEG, WebP, or PDF. Its API handles the browser runtime for you:

ScreenshotNeo removes common overlays before capture so the returned image is clean.
ScreenshotNeo removes common overlays before capture so the returned image is clean.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
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}`);

See the ScreenshotNeo API documentation for request options. Cookie and consent banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing result. ScreenshotNeo also provides an MCP server for AI agents, including 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 shots.

Create a free ScreenshotNeo account and start with 1,000 screenshots per month without a card.

FAQ

Does reinstalling Pyppeteer always fix launch failures?

No. Reinstallation cannot repair missing system libraries, an invalid executable path, incompatible system Chrome, or an unwritable profile.

Can I use Google Chrome instead of bundled Chromium?

Yes, with an explicit executablePath, but Pyppeteer does not guarantee compatibility with every separately installed Chrome or Chromium version.

Why does it work as my user but fail as a service?

The service may have a different home directory, permissions, PATH, browser cache, libraries, sandbox configuration, or writable temporary space.

Is Playwright automatically a fix?

No. It may be a sensible maintenance choice because the Pyppeteer repository describes itself as unmaintained, but the new runtime still needs a valid browser environment.