The error, verbatim
Jump to the fix ↓Error: Could not find Chrome (ver. 154.0.8037.57). This can occur if either
1. you did not perform an installation before running the script (e.g. `npx puppeteer browsers install chrome`) or
2. your cache path is incorrectly configured (which is: C:\Users\you\.cache\puppeteer).
For (2), check out our guide on configuring puppeteer at https://pptr.dev/guides/configuration.
# the same error for headless: 'shell':
Error: Could not find chrome-headless-shell (ver. 154.0.8037.57).
Tested on
- Puppeteer
- 25.11.0 / 25.12.0
- Node
- 24.14.0 / 24.21.0 (Linux)
- npm
- 11.9.0 / 12.2.0
- OS
- Windows 11 Pro, Ubuntu 24.04 (WSL)
Contents
- The fix that covers most cases01
- 1. The download was blocked or skipped at install02
- 2. You upgraded Puppeteer, the browser stayed behind03
- 3. Installed in one cache, run from another04
- 4. Docker and Linux: the download never unpacked05
- 5. Asking for the headless shell when only Chrome is installed06
- 6. Skip the download: use the Chrome already installed07
- What didn’t work08
- How this was tested09
Puppeteer doesn’t use the Chrome you have installed. It downloads its own build, pinned to the exact version in the message, into a cache folder during npm install. “Could not find Chrome” means that folder doesn’t hold that version. The message lists two reasons; in testing I found six ways to get there, and in most of them npm install had reported success.
The fix that covers most cases
Download the build Puppeteer is asking for, from the project folder:
npx puppeteer browsers install chromeIf the message says chrome-headless-shell, install that one instead (npx puppeteer browsers install chrome-headless-shell).
If it still fails, find your cause below. Each one comes back if you only patch it once.
1. The download was blocked or skipped at install
The browser download happens in Puppeteer’s postinstall script. Anything that stops install scripts stops the download, and npm install still succeeds:
- npm 12 blocks dependency install scripts by default. The only sign is a warning after the summary:
puppeteer@25.12.0 (postinstall: node install.mjs). The full list of what else that breaks: npm 12 breaking changes, tested. --ignore-scripts, common in CI and Dockerfiles for security.PUPPETEER_SKIP_DOWNLOAD=truein the environment, often left over from a guide.
I reproduced all three: each install exited cleanly, and each first launch failed with Could not find Chrome.
Run npx puppeteer browsers install chrome after the install step. On npm 12, you can also let the script run on every install:
npm install-scripts approve puppeteer
npm rebuild2. You upgraded Puppeteer, the browser stayed behind
Every Puppeteer release pins a new Chrome. I installed 25.11.0 (Chrome 153), then upgraded to 25.12.0 with scripts off:
chrome\win64-153.0.8010.36 <- what's in the cache
Could not find Chrome (ver. 154.0.8037.57) <- what 25.12.0 wants
The old build is still there, and it’s ignored: the version must match exactly. On npm 12 this happens even after you approved the script, because approvals are saved per version ("puppeteer@25.11.0": true) and the new version is blocked again.
npx puppeteer browsers install chrome after every Puppeteer upgrade. On npm 12, approve it by name so upgrades keep running the download:
npm install-scripts approve puppeteer --no-allow-scripts-pin3. Installed in one cache, run from another
The cache path is in the message: your cache path is incorrectly configured (which is: …). By default it’s .cache/puppeteer inside the home folder of the user running the command. So the browser goes missing when:
- you install as one user and run as another (a service account,
sudo, a DockerUSERline afternpm install), PUPPETEER_CACHE_DIRis set in one shell or CI step and not in the other,- a CI cache restores
node_modulesbut not the browser cache.
I installed with one cache folder and ran with another: same Could not find Chrome, with the second path printed in the message.
Make install and run use the same folder. The simplest way is a .puppeteerrc.cjs in the project root, which both the install script and your code read:
const { join } = require('path');
module.exports = { cacheDirectory: join(__dirname, '.cache', 'puppeteer') };That keeps the browser next to the project, whichever user runs it. Add .cache to .gitignore.
4. Docker and Linux: the download never unpacked
This one surprised me. On a clean Ubuntu 24.04 (WSL), npm install puppeteer@25.12.0 exited 0 and printed nothing about the browser. The Chrome folder existed, and was empty. Running the download by hand showed why:
Error: All providers failed for chrome 154.0.8037.57:
- DefaultProvider: Extraction failed: no zip archiver is available.
Install `unzip` (or `tar.exe`/Powershell on Windows), or add the optional `yauzl` dependency.
Puppeteer 25 unpacks Chrome with the system’s unzip, and slim Linux images don’t have it. Then the half-finished folder blocks every retry:
The browser folder (…/chrome/linux-154.0.8037.57) exists but the executable (…/chrome-linux64/chrome) is missing.
An earlier install of this build probably did not finish. Delete … and install the browser again.
Give it an unzipper, delete the empty folder, download again. Without root, the option the error names works:
npm install yauzl
npx puppeteer browsers install chromeIn a Dockerfile, installing unzip with the system package manager before npm install does the same job.
5. Asking for the headless shell when only Chrome is installed
With headless: 'shell', Puppeteer wants a separate download:
Could not find chrome-headless-shell (ver. 154.0.8037.57). This can occur if either
1. you did not perform an installation before running the script (e.g. `npx puppeteer browsers install chrome-headless-shell`)
A normal npm install downloads both. Installing only chrome by hand doesn’t. In my test, the same cache launched fine with the default headless and failed with 'shell'.
npx puppeteer browsers install chrome-headless-shellOr drop headless: 'shell': the default headless mode uses the full Chrome you already have.
6. Skip the download: use the Chrome already installed
If the machine has Google Chrome, Puppeteer can use it, and none of the above applies:
const browser = await puppeteer.launch({ channel: 'chrome' });The trade-off: your Chrome updates on its own schedule, not Puppeteer’s. Here it was 154.0.8037.93 against the pinned 154.0.8037.57, which worked. A bigger gap can break things, which is exactly why Puppeteer pins a version.
What didn’t work
How this was tested
Windows 11 with Node 24.14.0 and npm 11.9.0, plus npm 12.2.0 on Node 26.10.0, and Ubuntu 24.04 under WSL with Node 24.21.0. Every cause used its own empty cache folder, so nothing downloaded earlier could hide a failure. Each case was a real install followed by a real puppeteer.launch(), and each fix was confirmed by a launch that printed the browser version. All error text above is copied from those runs.
— N.K., end of entry No.040