How Puppeteer’s Default Browser Provider Checks Browser Support
Puppeteer checks each browser provider in order for the requested browser, platform, and build ID. Learn how `supports`, download URLs, `canDownload`, and the default fallback differ.
Puppeteer checks browser support by asking each configured provider whether it handles the requested browser, platform, and build ID. It skips a provider when supports returns false; if support is true, it asks for a download URL. A missing URL or an installation error moves the flow to the next provider. Provider support is not proof that a remote archive exists or that the browser binary will run.
This distinction is useful when diagnosing a failed install: provider capability, download availability, and Puppeteer/browser version compatibility are separate checks.
1. The provider check, step by step
- Resolve the platform. If you omit
platform, Puppeteer uses automatic detection. If it cannot determine a platform, installation errors instead of trying a download. - Build the provider sequence. Supplied providers go first. A supplied
baseUrladds aDefaultProviderconfigured with that URL. The ordinary default provider is appended when there is nobaseUrl, or whenforceFallbackForTestingis enabled. - Call
supports. The installation loop passes the requested browser, platform, and build ID to the provider. The implementation describes this as checking whether the provider supports “this browser/platform.” - Skip unsupported providers. A false result advances to the next provider.
- Ask for a URL. If the provider returns no URL, installation continues to the next provider. When a URL is returned, Puppeteer tries to install from it.
- Continue after failures. Errors from an attempted provider are recorded while the loop tries later providers. If every provider fails, Puppeteer throws an error reporting the provider failures.
See the [installation implementation](https://github.com/puppeteer/puppeteer/blob/main/packages/browsers/src/install.ts) for the provider loop and InstallOptions for the public options. The repository link follows main, so it can change as Puppeteer develops.
2. Three meanings of “supported”
| Question | What answers it | What it does not prove |
|---|---|---|
| Does this provider handle this browser/platform/build? | The provider’s supports decision. |
That a remote archive exists or can be downloaded. |
| Can the archive URL be reached? | canDownload obtains a URL and makes an HTTP HEAD request; it returns true when a check succeeds. |
That the installed browser will launch or is compatible with your Puppeteer release. |
| Which browser release is documented for this Puppeteer release? | The supported-browsers mapping for the relevant Puppeteer version. | That a custom provider’s binary has been tested by Puppeteer. |
In short, supports is a provider routing decision. It is not a runtime feature test, a connectivity test, or a compatibility guarantee.
3. Provider order and fallback behavior
Provider order matters because the installation loop tries providers in sequence. With custom providers, Puppeteer asks those providers first. In the ordinary configuration, the default provider is available as the final fallback. Adding baseUrl changes how that default fallback is arranged; forceFallbackForTesting forces the ordinary default provider to be appended even when a base URL is supplied.
| Configuration | Effect on sequence |
|---|---|
Custom providers, no baseUrl |
Custom providers first, then the ordinary default provider. |
baseUrl supplied |
A default provider configured for that base URL is added; the ordinary default fallback is not appended by default. |
baseUrl and forceFallbackForTesting |
The base-URL provider is added and the ordinary default provider is also appended. |
Exact option availability can vary by package version. Consult the API documentation matching the @puppeteer/browsers version in your lockfile.
4. Inspect the installation options
This runnable Node.js example shows the public shape of an install request. It uses the package’s default provider flow and an explicit browser and build ID. Install the package first with npm install @puppeteer/browsers. Replace the build ID with one that is valid for the browser and platform you intend to install; a build ID is not interchangeable across browser releases.
import { install, Browser, detectBrowserPlatform } from '@puppeteer/browsers';
const platform = detectBrowserPlatform();
if (!platform) {
throw new Error('Could not detect a supported browser platform');
}
const installed = await install({
browser: Browser.CHROME,
buildId: '131.0.6778.204',
platform,
cacheDir: './.cache/puppeteer',
});
console.log('Installed browser at:', installed.executablePath);
The example demonstrates platform detection and installation options; the particular build ID may no longer be the browser version documented for your Puppeteer release. Use the version-appropriate entry in Puppeteer’s supported browsers guide. The official API calls the platform value a BrowserPlatform, meaning an operating-system and architecture combination. Relevant installation options include the browser, build ID, platform, cache directory, providers, and base URL. Option types may evolve, so check the versioned API reference.
Check archive availability separately
When the question is whether a provider’s URL can be reached, use the separate canDownload check supported by @puppeteer/browsers, with the same browser, platform, build ID, and provider configuration as the installation attempt:
import {
canDownload,
Browser,
detectBrowserPlatform,
} from '@puppeteer/browsers';
const platform = detectBrowserPlatform();
if (!platform) {
throw new Error('Could not detect a supported browser platform');
}
const available = await canDownload({
browser: Browser.CHROME,
buildId: '131.0.6778.204',
platform,
});
console.log('Download URL reachable:', available);
canDownload is an availability probe, not a launch test. It makes an HTTP HEAD request after obtaining a URL. A server or proxy that treats HEAD differently from GET can affect the result; a true result also cannot guarantee that the later transfer or extraction will succeed.
5. How to diagnose a provider decision
- Record the exact request. Note the browser name, platform, build ID, package version, and whether
baseUrlor custom providers are configured. - Check the platform. If detection returns no platform, resolve the supported platform explicitly for the host environment or use a supported runtime.
- Check each provider in order. Determine which providers receive the request and whether each claims the specific browser/platform combination.
- Check URL generation. A provider can report support and still return no URL for a particular build ID.
- Probe availability. Use
canDownloadwhen you need to distinguish URL reachability from provider support. - Compare compatibility separately. Match your installed Puppeteer version to its documented browser version rather than using a mapping from another release.
- Review the final error. If installation reports provider failures, inspect the recorded failures in sequence; an early provider failure may be followed by a successful fallback.
6. Custom providers and compatibility responsibility
Puppeteer’s documentation says custom providers are not officially supported. A custom provider’s supports result expresses that provider’s own capability; it does not certify that the binary is compatible. Puppeteer tests and guarantees compatibility with its default binaries, while users of custom providers are responsible for binary compatibility, testing, and maintenance.
For a compatibility claim, verify the browser release mapping for the exact Puppeteer version, then test the binary and application behavior in the target environment. The supported browsers guide notes that when an exact Puppeteer version is absent from the table, the browser version for the immediately prior Puppeteer release applies.
7. Browser and installation context
- Puppeteer downloads and uses a specific Chrome version by default. Its configuration guide also documents selecting another Chrome or Chromium executable through an executable path.
- The installation guide describes automatic downloads of a compatible Chrome for Testing version and a
chrome-headless-shellbinary; the latter began with Puppeteer v21.6.0. - The guide identifies
$HOME/.cache/puppeteeras the default browser cache location beginning with v19.0.0. - These are version-scoped defaults. Check the guide for your installed release instead of assuming every version and environment behaves the same way.
Sources: Puppeteer configuration, Puppeteer installation, and supported browsers.
8. Common problems and fixes
| Symptom | Likely cause | What to do |
|---|---|---|
| No browser download is attempted. | Platform detection failed, or every provider returned false from supports. |
Confirm the host OS and architecture, inspect the resolved platform, and verify the provider sequence handles that combination. |
| A provider is skipped despite appearing to support the browser. | Its support decision may be specific to the requested platform or build ID. | Log the full browser/platform/build request and inspect the provider’s condition for each field. |
supports is true but installation continues elsewhere. |
The provider returned no download URL, or installing from its URL failed. | Check URL generation for that build ID and inspect the provider error before the fallback result. |
canDownload is false but the provider claims support. |
The support decision passed, but the generated URL did not pass the HEAD request. | Check URL construction, network access, proxy rules, and server handling of HEAD requests. |
| The configured mirror is used but the expected default source is not. | baseUrl changes the fallback arrangement. |
Review the provider sequence and, where appropriate for the installed API version, configure forceFallbackForTesting. |
| The browser downloads but does not work with Puppeteer. | Provider support and download success do not establish binary compatibility. | Use the release mapping for your Puppeteer version and validate custom binaries in your own environment. |
| The build cannot find a previously downloaded browser. | The configured cache directory differs from the location used during installation, or the version’s defaults differ. | Use the same cache configuration in install and runtime environments, and confirm the version-specific default path. |
9. Performance, reliability, and cost considerations
Provider order affects install latency: each false support result or missing URL adds another provider check, and failed download attempts can add network and extraction time before a fallback succeeds. Keep the provider list focused, make support decisions quickly, and avoid generating URLs for builds the provider cannot supply.
Reliability depends on more than supports. A healthy setup needs a correct platform choice, a URL for the requested build, reachable storage, successful transfer and extraction, a usable cache path, and a compatible binary. A fallback can improve resilience when configured, but it only helps if the later provider can serve the same requested build.
Cost is determined by where the binary is hosted and how it is downloaded; Puppeteer’s provider check itself does not establish a price. Account for mirror storage, bandwidth, CI cache misses, and repeated downloads in your own hosting setup. No specific benchmark or cost figure follows from the provider-support behavior.
10. FAQ
Does DefaultProvider.supports test whether Chrome launches?
No. It determines whether the provider handles the requested browser/platform combination. Launchability must be established separately by running the downloaded binary.
Does Puppeteer check whether the download URL exists?
The installation loop asks for a URL and then attempts installation. The separate canDownload function performs a HEAD request to check reachability.
Does a custom provider reporting support mean Puppeteer guarantees compatibility?
No. Puppeteer assigns custom-provider binary compatibility and testing responsibility to the user.
Which browser version should I request?
Use the supported-browser mapping for the Puppeteer release in your project. Do not treat a build ID from another release as a universal compatibility target.
Or skip the browser setup
If your goal is to get a page image instead of managing a browser binary, ScreenshotNeo offers a website screenshot API and MCP server. Its screenshot call accepts a URL and returns an image or PDF; see the API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month, with no card.


