Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Set headless: false to request a visible Chrome window, then diagnose the host that must display it. On Ubuntu, headed Puppeteer failures usually come from one of three separate causes: no accessible graphical display, missing Chrome/Linux libraries, or a sandbox policy that blocks Chrome. The correct fix depends on the exact log and environment.

1. Request headed Chrome explicitly

Puppeteer launches headless Chrome by default. A minimal headed launch is:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
    headless: false
  });
  const page = await browser.newPage();
  await page.goto('https://example.com', {waitUntil: 'networkidle2'});
  // Keep the window open while testing.
  await new Promise(resolve => setTimeout(resolve, 10000));
  await browser.close();
})();

headless: false changes the browser mode; it does not create a display server. If this code runs in a desktop session and still exits, continue with the host checks below. For current Puppeteer releases, verify the Node requirement and supported browser details on the system requirements page. The retrieved Puppeteer guide lists Node.js 22.12 or newer for its current support statement and Debian/Ubuntu on x64 and arm64.

2. Determine whether Ubuntu provides a display

Desktop session

On a normal Ubuntu desktop, the process must run as a user with access to the active graphical session. Check the display-related environment before blaming Puppeteer:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
echo "$DISPLAY"
echo "$WAYLAND_DISPLAY"
printenv XDG_RUNTIME_DIR

An empty display variable is a strong indication that the process cannot find an X11 display. A process launched through a service, SSH session, cron job, container, or CI runner may not inherit the desktop session even when Ubuntu itself has a monitor attached.

CI, server, or container

A machine without a desktop needs a virtual display for non-headless Chrome. Puppeteer’s troubleshooting guide specifically advises starting Xvfb for headed Chrome in CI. Install and start it using your distribution’s current packages, then run Puppeteer with the display it created. A common test pattern is:

Xvfb :99 -screen 0 1920x1080x24 &
export DISPLAY=:99
node app.js

The exact service command varies by CI image. Confirm that Xvfb is still running and that the Puppeteer process has permission to connect to DISPLAY=:99. Xvfb supplies pixels to a virtual framebuffer; it does not make a visible window appear on a remote monitor.

If you need an actual visible window, use a real graphical Ubuntu session or a remote desktop arrangement. Do not expect headless: false alone to provide one.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

3. Check Chrome’s shared libraries

When Chrome cannot load a required Linux library, errors often mention a missing shared object or terminate before a window appears. Inspect the actual Chrome binary that Puppeteer is launching:

ldd /path/to/chrome | grep not

Replace the path with the executable reported by your installation or Puppeteer configuration. The command prints unresolved libraries. Ubuntu Chrome commonly needs GTK, NSS, GBM, X11 and font-related runtime components. The complete package set changes with browser and Ubuntu versions, so use the current Puppeteer troubleshooting guidance and the requirements for the Chrome build you installed rather than copying an old blog list.

For Chrome managed by Puppeteer on Ubuntu or Debian, the browser CLI documents:

npx puppeteer browsers install chrome --install-deps

This uses apt-get and therefore requires system-level privileges. Run it in an environment where installing packages is permitted, then retry the same launch. If your application uses a system Chrome rather than Puppeteer’s downloaded Chrome, install dependencies for that specific binary and ensure your executablePath points where you expect.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

4. Resolve “No usable sandbox!” safely

Chrome’s sandbox isolates browser content and is a security boundary. Puppeteer states that the recommended way to run Chrome is with sandboxes and strongly discourages disabling them. Do not make --no-sandbox your default Ubuntu fix.

Ubuntu 23.10 and newer AppArmor scenario

Puppeteer documents a particular failure on Ubuntu 23.10 and later: an AppArmor profile for Chrome Stable at /opt/google/chrome/chrome can prevent Chrome for Testing downloaded by Puppeteer from using user namespaces. That mismatch can produce the exact message No usable sandbox!. Check whether this documented combination matches your host, browser and error, then follow the Chromium AppArmor user-namespace guidance referenced by Puppeteer and your organization’s security policy.

Do not assume every sandbox error is caused by AppArmor. Check the kernel, user-namespace availability, container restrictions and which Chrome binary is actually running. If you temporarily test with:

const browser = await puppeteer.launch({
  headless: false,
  args: ['--no-sandbox']
});

treat that as an exceptional, security-reducing diagnostic for fully trusted content and isolated environments. Restore sandboxed operation for normal workloads.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

5. Turn on launch diagnostics

When the visible error is vague, forward Chrome’s own output to Node:

const browser = await puppeteer.launch({
  headless: false,
  dumpio: true
});

Capture the complete output and record:

  • the exact error text, including punctuation;
  • the Puppeteer version (the current headless guide retrieved for this topic identifies version 25.12.0);
  • Chrome executable path and version;
  • Ubuntu release and CPU architecture;
  • whether the process runs in CI, a container, SSH, or a desktop session;
  • whether DISPLAY or a Wayland session is available.

These facts separate display, dependency and sandbox branches far faster than changing launch flags at random.

6. Match the symptom to the next action

Symptom or environment Likely area Next evidence-led step
No usable sandbox! Sandbox configuration; on Ubuntu 23.10+, possibly AppArmor and user namespaces Check the documented Ubuntu scenario, browser path and security policy. Keep the sandbox enabled whenever possible.
Missing shared object or library-load error Linux runtime dependencies Run ldd ... | grep not on the actual binary and install current required packages.
Works on a desktop, fails in CI or on a server No display accessible to headed Chrome Start Xvfb for CI, export its display, and verify the process can connect.
Chrome exits with little or no explanation Hidden browser-process output Set dumpio: true and inspect Chrome’s logs.

7. Container-specific checks

Puppeteer’s Docker guidance describes an image containing Chrome for Testing and its dependencies. Its documented sandboxed run requires the SYS_ADMIN capability and recommends an init process to manage browser children. Your container still needs a display service for headed mode: container permissions, Xvfb (or a real display), and the DISPLAY value must agree.

If a container is deliberately restricted and cannot provide the sandbox or display required by your security model, headless mode may be the appropriate design. That is an environment decision, not evidence that headless: false is malformed.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
The SQL Programming Language: .
  • Used Book in Good Condition
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

8. A repeatable repair procedure

  1. Run the smallest launch with headless: false and dumpio: true.
  2. Classify the log as display, library, sandbox or another browser error.
  3. For display errors, test DISPLAY and start Xvfb in CI or a server.
  4. For library errors, inspect the binary with ldd and install dependencies for that Chrome build.
  5. For sandbox errors, verify the browser path, user namespaces, container permissions and the Ubuntu 23.10+ AppArmor case.
  6. Retry without unrelated flags and keep a record of the working environment.

Or skip the browser setup

If your goal is a page image or PDF rather than controlling a visible Chrome window, ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; failed loads, bot checks, blank pages, timeouts and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP tools—take_screenshot, get_page_info and capture_pdf—work with Claude, Cursor and other MCP clients.

One request is enough:

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

See the ScreenshotNeo API documentation for options such as full-page capture, element selectors, device presets, custom CSS/JavaScript, waits, request blocking, cookies, headers, geolocation, PDFs, signed links, caching, asynchronous webhooks and bulk capture.

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}`);

The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Sign up free.

FAQ

Does headed mode work with Chrome for Testing?

Yes. Puppeteer’s supported-browsers documentation says that, starting with Puppeteer 20.0.0, Puppeteer downloads Chrome for Testing, which supports both headless and headful operation through the same browser code path.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why does setting headless: false not show a window over SSH?

An SSH process normally has no connection to your desktop display. Use a configured graphical session or Xvfb, and ensure the process has permission to access the selected display.

Should I downgrade Ubuntu to fix Chrome?

No. First identify whether the failure is a missing dependency, unavailable display or sandbox policy. The documented AppArmor complication is specific to a particular Ubuntu 23.10+ and Chrome-for-Testing arrangement.

Frequently Asked Questions

Can I use headed Puppeteer without installing a desktop environment?

Yes, but you still need a display server such as Xvfb. A desktop environment is not required when a virtual display is configured and accessible.

Where should I report a reproducible launch failure?

Include the exact dumpio output, Puppeteer and Chrome versions, Ubuntu release, executable path, container or CI details, and display variables so the failure can be classified accurately.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.