Puppeteer browser launch configuration for Chromium version mismatches
0 reputation · 25 Aug 2026, 09:02 UTC
0 reputation · 25 Aug 2026, 09:02 UTC
Puppeteer manages the browser lifecycle via the puppeteer.launch() method, which by default relies on a bundled Chromium binary compatible with the installed library version. In environments where the system-installed browser is updated independently of the Puppeteer package, a version mismatch can prevent the browser from initializing.
While the executablePath option allows pointing to a specific binary, there is uncertainty regarding the most reliable way to programmatically detect a version incompatibility before the launch process fails. Ensuring the library version aligns with the binary version is critical for maintaining stability in automated CI/CD pipelines.
puppeteer.launch()?There is no built-in pre-flight compatibility check and no automatic fallback binary in Puppeteer. The reliable strategy is the opposite of probing: pin the browser to the exact build your Puppeteer version expects, let Puppeteer manage it via its cache, and verify the resolved version at runtime with browser.version(). If you must use a custom executablePath, the practical "detection" is a cheap launch probe with dumpio: true so the real Chromium error surfaces instead of a generic timeout.
Each Puppeteer release is tested against a specific Chrome for Testing revision. By default, puppeteer.launch() downloads and uses that pinned build from its cache (typically ~/.cache/puppeteer, overridable via PUPPETEER_CACHE_DIR or a .puppeteerrc file). Mismatches almost always come from one of three sources:
executablePath pointing at a system Chrome/Chromium that updates independently.PUPPETEER_SKIP_DOWNLOAD / PUPPETEER_SKIP_CHROMIUM_DOWNLOAD forcing reliance on whatever binary the environment provides.The failure mode is usually a DevTools protocol error (target closed, WebSocket disconnect) rather than a clean "version mismatch" message, because the protocol evolves between Chrome versions. Matching only the major version is often not enough.
npx puppeteer browsers install chrome Then launch with no executablePath override. This removes the mismatch class entirely.const browser = await puppeteer.launch({ dumpio: true });
console.log(await browser.version()); Compare this against the revision listed in your Puppeteer version's release notes. A startup assertion that fails the CI job on drift is cheaper than a pre-launch probing scheme.channel: 'chrome' (or an explicit executablePath) and treat the first launch as the probe: wrap it in try/catch, and on failure re-run with dumpio: true to capture Chromium's stderr. That output distinguishes a version/protocol failure from sandbox or missing-dependency errors.Puppeteer has no flag to automatically try a second binary when the first fails. If you need fallback behavior, implement it yourself: attempt launch with the pinned cache build first, catch the error, then retry with executablePath pointing at the system binary — and log which path succeeded so drift is visible. Keep the fallback list short and explicit; silently landing on an untested browser version is worse than a loud failure.
Option names, cache paths, and supported channels vary across Puppeteer major versions; the above reflects recent releases — check the changelog for your installed version. Also note that in containers, --no-sandbox failures when running as root are frequently mistaken for version mismatches; dumpio: true output separates the two.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 25 Aug 2026, 19:47 UTC
Before calling puppeteer.launch() you can verify that the binary you plan to use matches the revision Puppeteer expects. The package exposes the expected revision via puppeteer.defaultChromiumRevision() and the resolved binary path via puppeteer.executablePath().
const puppeteer = require('puppeteer');
const { execSync } = require('child_process');
const expectedRev = puppeteer.defaultChromiumRevision();
const binary = puppeteer.executablePath();
const actualVersion = execSync(`${binary} --version`).toString().trim();
console.log('Expected revision:', expectedRev);
console.log('Binary version:', actualVersion);
// Optional: compare numeric parts or map revision → release via internal revisions.js
Parsing the --version output must be tolerant of both Chromium 121.0.6167.120 and Google Chrome 121.0.6167.120 formats. If the numeric part diverges from the revision mapping, the launch is likely to fail with a protocol error.
Puppeteer does not offer an automatic fallback flag. If you need resilience, wrap puppeteer.launch() in a try…catch loop that retries with an alternate executablePath when the first attempt throws.