Recommended Free Tools
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
If Puppeteer launches Chrome from your terminal but fails under PM2, first compare the running PM2 process’s user, HOME, PATH, and Puppeteer cache with the shell where it works. Then confirm that Chrome is installed and that any configured executablePath names a real executable on the PM2 host. Only investigate sandbox settings after you have ruled out browser discovery and environment differences: “Could not find Chrome,” “No usable sandbox,” and navigation timeouts have different causes and fixes.
Start with the exact PM2 error
Do not begin by adding Chrome flags at random. Capture the complete error from the PM2 process; the first useful distinction is whether Chrome was not found, could not be launched because of sandbox or permissions, or launched but failed while loading a page.
pm2 logs renderer --lines 100
pm2 describe renderer
Replace renderer with your PM2 app name. Save the full stderr message, including any path or browser version in it. “Could not find Chrome” points toward installation, cache, or environment. “Tried to find the browser at the configured path … but no executable was found” points toward a bad path. “No usable sandbox!” is a host security configuration problem. A navigation timeout happens later in the process and should not be treated as proof that Chrome is missing.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Check what PM2 actually runs
A terminal session and a PM2-managed process can use different Unix users, working directories, environment variables, and browser caches. A browser installed under one account’s home directory may be invisible to an app running as another account. Likewise, a path that exists in your SSH session may not be in PM2’s PATH.
#1 Best Overall
- CRISP CLARITY: This 23.8″ Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
- WORK SEAMLESSLY: This sleek monitor is virtually bezel-free on three sides, so the screen looks even bigger for the viewer. This minimalistic design also allows for seamless multi-monitor setups that enhance your workflow and boost productivity
- A BETTER READING EXPERIENCE: For busy office workers, EasyRead mode provides a more paper-like experience for when viewing lengthy documents
Inspect the process identity and environment
Check the account PM2 uses to manage the app and the account configured for the app. Compare the effective values of HOME, PATH, PUPPETEER_CACHE_DIR, and PUPPETEER_EXECUTABLE_PATH in the running process against the working shell. One practical diagnostic is to log them briefly from the application itself:
console.log({
uid: process.getuid?.(),
cwd: process.cwd(),
home: process.env.HOME,
path: process.env.PATH,
puppeteerCache: process.env.PUPPETEER_CACHE_DIR,
puppeteerExecutable: process.env.PUPPETEER_EXECUTABLE_PATH
});
Remove or redact this diagnostic after troubleshooting if logging the environment would expose sensitive values. The fields shown here do not include secrets such as API keys, but your wider environment may.
Account for PM2’s environment update behavior
PM2 does not necessarily pick up changes made to the shell environment after the application was started. If you change variables from the CLI environment, restart with --update-env:
Free tools Windows power users keep installed
One-click scans. No signup required.
pm2 restart renderer --update-env
If your settings live in an ecosystem file, restart or reload using that file so PM2 applies the file’s environment settings. For example, when using an env_production block, start the app with --env production and use the ecosystem file for later restarts as well:
Rank #2
- CRISP CLARITY: This 22 inch class (21.5″ viewable) Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- 100HZ FAST REFRESH RATE: 100Hz brings your favorite movies and video games to life. Stream, binge, and play effortlessly
- SMOOTH ACTION WITH ADAPTIVE-SYNC: Adaptive-Sync technology ensures fluid action sequences and rapid response time. Every frame will be rendered smoothly with crystal clarity and without stutter
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
pm2 start ecosystem.config.js --env production
pm2 restart ecosystem.config.js --env production
Install or locate a browser PM2 can use
The standard puppeteer package normally downloads a compatible Chrome for Testing browser and a chrome-headless-shell as part of its installation. If a package manager blocked install scripts, that download may not have happened. A successful application install does not by itself prove that the browser binary is present.
Use Puppeteer’s managed browser
From the project directory and under the same account and cache configuration as the PM2 app, install the browser with:
npx puppeteer browsers install
Then make sure that account can read and execute the installed browser and can access its cache directory. If you install the browser as one user but run the app as another, either install it for the PM2 user or deliberately configure a shared cache with permissions appropriate to that user. Avoid “fixing” a permissions problem by making the entire cache world-writable.
Know what changes with puppeteer-core
puppeteer-core does not download or choose a default browser for you. You must manage the browser installation and tell Puppeteer where it is. It also ignores Puppeteer configuration files and environment variables, so pass settings such as executablePath directly to launch() when using it.
Rank #3
- Clear visuals. Fluid motion: A 144Hz refresh rate and 1ms MPRT deliver smooth, tear‑free motion across work, gaming, and streaming for clearer, more fluid viewing.
- Eye comfort: TÜV Rheinland 3‑star* certification reduces harmful blue light while preserving stunning color quality without compromise. *TÜV Rheinland 3-star eye comfort certification.
- Wide viewing angle: Get consistent views across a wide 178° /178° viewing angle.
- In-Plane Switching (IPS): See excellent color accuracy and consistency across wide viewing angles with In-plane Switching (IPS) technology.
- Ultra-thin bezels: Maximize your viewing experience with thin bezels.
Set a real executablePath when needed
Use an absolute path to a browser executable that exists on the PM2 host. A path copied from a laptop, a stale override, or a directory that contains an application bundle is not a usable executable path. Check likely system-browser locations as the PM2 user:
command -v google-chrome
command -v chromium
command -v chromium-browser
Only use the command that actually returns a path on your host. If you rely on Puppeteer’s downloaded browser instead of a system browser, use the path produced by the installer or let Puppeteer find its managed browser; do not assume a specific cache location.
Here is a minimal CommonJS ecosystem configuration for an app that uses an explicitly configured browser. The path and cache location are examples, not universal Linux paths. Change them to match the files and permissions on your host.
// ecosystem.config.js
module.exports = {
apps: [{
name: 'renderer',
script: './server.js',
env_production: {
NODE_ENV: 'production',
PUPPETEER_EXECUTABLE_PATH: '/usr/bin/google-chrome-stable',
PUPPETEER_CACHE_DIR: '/var/lib/renderer/.cache/puppeteer'
}
}]
};
Pass the configured path to Puppeteer explicitly, particularly if you want the application’s launch behavior to be clear and predictable:
Rank #4
- CURVED FOR ENHANCED ENGAGEMENT: An immersive viewing experience with a curved monitor that wraps more closely around your field of vision; It creates a wider view, enhancing depth perception and minimizing peripheral distraction
- SMOOTH PERFORMANCE FOR SEAMLESS CONTENT: Stay in the action when playing games, watching videos, or working on creative projects; The 100Hz refresh rate reduces lag and motion blur so you don't miss a thing in fast-paced moments¹
- MORE GAMING POWER: Gain the edge with optimizable game settings; Color and image contrast can be adjusted to see scenes more vividly and spot enemies hiding in the dark; Game Mode adjusts any game to fill the screen so you can view every detail²
- KEEP IT EASY ON THE EYES: Care for your eyes and stay comfortable, even during long sessions; Advanced eye comfort technology certified by TÜV reduces eye strain by minimizing blue light and reducing irritating screen flicker²
- INCREASED VERSATILITY: Connect to more; Plug devices straight into your monitor for increased flexibility, making your computing environment even more convenient
const puppeteer = require('puppeteer');
async function main() {
const executablePath = process.env.PUPPETEER_EXECUTABLE_PATH;
if (!executablePath) {
throw new Error('PUPPETEER_EXECUTABLE_PATH is not set');
}
const browser = await puppeteer.launch({
executablePath,
headless: true
});
try {
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
console.log(await page.title());
} finally {
await browser.close();
}
}
main().catch(error => {
console.error(error);
process.exitCode = 1;
});
This example deliberately fails with a clear message if the path variable is absent. If you are using puppeteer-core, set the path in the launch() options in the same way; do not rely on Puppeteer configuration or environment-variable defaults being applied to that package.
Fix sandbox errors without weakening isolation by default
Chrome’s Linux sandbox is a host security boundary, not a browser-discovery setting. “No usable sandbox!” can indicate that the host lacks the required sandbox setup, that the process is running in an unsuitable privilege context, or that a policy such as an AppArmor user-namespace restriction prevents Chrome from using it. Some Ubuntu releases impose AppArmor restrictions relevant to Chrome’s user namespaces.
Prefer configuring the host’s supported Chrome sandbox and running the application as a non-privileged user. Puppeteer’s troubleshooting guidance also describes setuid-sandbox setup for relevant environments; follow the instructions applicable to your distribution and browser installation rather than applying permissions copied from a different host.
--no-sandbox is not a general fix for a Chrome startup failure. It weakens browser isolation and is explicitly discouraged by Puppeteer. Consider it only as a last resort for trusted content when you understand and accept the security trade-off; it should not be used to paper over an unexplained production configuration problem.
Best Value
- 【INTEGRATED SPEAKERS】Whether you're at work or in the midst of an intense gaming session, our built-in speakers provide rich and seamless audio, all while keeping your desk clutter-free.
- 【EASY ON THE EYES】 Protect your eyes and enhance your comfort with Blue-Light Shift technology. This feature reduces harmful blue light emissions from your screen, helping to alleviate eye strain during long hours of use and promoting healthier viewing habits.
- 【WIDEN YOUR PERSPECTIVE】Our sleek minimal bezel design ensures undivided attention. The nearly bezel-free display seamlessly connects in a dual monitor arrangement, delivering an unobstructed view that lets you focus on more at once, completely distraction-free.
Troubleshoot by symptom
| PM2 symptom | Likely cause | What to do |
|---|---|---|
Could not find Chrome (ver. …) |
The browser download was skipped, the PM2 process uses a different home or cache, or the configured browser location is stale. | Install the browser in the same project and cache environment used by PM2; align the app’s user and cache permissions; remove stale overrides. |
Tried to find the browser at the configured path … but no executable was found |
The configured path does not exist, is not executable, or points to a directory rather than the browser binary. | Check the path on the PM2 host as the app user. Remove the override or replace it with the existing absolute executable path. |
No usable sandbox! |
The host’s sandbox capability or policy is incompatible with the current execution context. | Configure the host sandbox and use an appropriate non-privileged account. Treat --no-sandbox as a security-reducing last resort, not a routine remedy. |
| Works in SSH, fails under PM2 | The PM2 app has a different user, HOME, PATH, cache, or stale environment. |
Inspect the running app’s effective values, set the intended variables in the ecosystem file, and restart using the file or --update-env as appropriate. |
| Chrome child processes remain after restarts | Shutdown or process reaping is not cleaning up browser children, a concern in some PID 1 or container setups. | Review how the host or container handles process shutdown and reaping, and verify that the application closes the Puppeteer browser during normal shutdown. |
| Browser starts but page navigation times out | The failure occurs during page loading rather than browser discovery. | Keep the full navigation error and diagnose the page-load condition separately. Do not change the executable path or sandbox flags unless the error points to those layers. |
Keep restarts and browser processes reliable
Once Chrome starts, make sure the app closes browser instances when its work finishes and during orderly shutdown. The example above closes its browser in a finally block, so a page error does not skip cleanup. For a long-running service that reuses a browser, add shutdown handling appropriate to the application and confirm that PM2’s stop/restart behavior actually terminates its child processes.
In container or PID 1 environments, a process-reaping strategy may be necessary to prevent orphaned or zombie child processes. This is a lifecycle issue, not a reason to reinstall Chrome. Also account for browser compatibility when choosing between Puppeteer’s downloaded browser and a system browser: the managed download is convenient and tied to Puppeteer’s installation, while a system browser gives you more operational control but requires separate package and version maintenance.
Or skip the browser setup
If your goal is to capture website screenshots rather than run your own local Chrome process, ScreenshotNeo provides a screenshot API and MCP server. A single request can return a screenshot or PDF; its API uses familiar screenshot parameters, which can make switching easier. This avoids installing and operating Chrome in your PM2 app, but it is an alternative capture service—not a fix for a PM2 browser process you still need for other work.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
For example, this Node.js request captures a page and writes the response body to a file. See the ScreenshotNeo API documentation for request options and response handling:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));
The service 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 or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and responses identify the page verdict and billing status in headers. An MCP server offers 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 monthly plans start at $5 for 3,000 screenshots; yearly billing gives two months free. Every feature is available on every plan. Sign up for 1,000 free screenshots a month with no card.
Frequently Asked Questions
Does PM2 install Chrome when it starts an app?
No. PM2 manages the Node.js process; browser installation and cache availability are handled by your Puppeteer package and deployment setup.
Will changing the browser path fix a sandbox error?
Not by itself. A valid path solves browser discovery; a “No usable sandbox!” error requires investigating the host’s sandbox and security policy.
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.

