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

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Headless Chrome results can differ from normal Chrome because “headless” has referred to two different Chrome implementations, and because rendering also depends on the browser build and host environment. Chrome introduced a unified Headless mode in version 112; the older implementation was later moved out of the Chrome binary in version 132. For a reliable comparison, record the exact Chrome, ChromeDriver and Selenium versions and launch arguments, then hold the page, viewport, timing and machine conditions constant.

What the headless argument actually changes

Headless mode runs Chrome without displaying its usual browser window. But old advice that treats --headless and --headless=new as interchangeable may describe different browser behavior, depending on the Chrome version and Selenium binding in use.

Chrome’s older Headless mode was a separate implementation. Chrome for Developers explains that separation meant it could have its own bugs and features that were not present in headful Chrome. Chrome 112 introduced a unified Headless mode: Chrome runs without creating platform windows while sharing the browser’s functionality with regular Chrome. In Chrome 132, the old implementation was moved out of the Chrome binary into a separate chrome-headless-shell binary. See Chrome’s New Headless mode documentation and the Chromium Headless README.

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

Selenium’s 2023 migration post says its headless convenience method selected Chromium’s initial implementation at that time, and showed --headless=new to select the newer mode. That is useful historical context, not a guarantee about every current binding or Chrome build. Check the installed versions and the actual arguments sent to Chrome rather than assuming an old snippet still selects the same implementation. Read Selenium’s Headless migration post.

Unified Headless reduces the old implementation split, but it does not promise identical output across every Chrome release, operating system, GPU, viewport, font set, timing condition or website. A screenshot difference is a symptom to investigate, not proof that headless mode always loads sites differently.

Start with the versions and launch arguments

Before changing waits or adding flags, make a record of the test environment. Selenium’s Chrome documentation says Chrome and ChromeDriver must have matching major versions. Capture exact versions as well as the major numbers, since that record helps make a comparison reproducible. The same documentation is maintained at Selenium’s Chrome-specific functionality page.

  • Chrome version and ChromeDriver version, including their major versions.
  • Selenium version and language binding.
  • Every Chrome argument, including whether the run uses --headless, --headless=new, or another mode-specific option.
  • Operating system or container image, and whether a display server is available.
  • GPU and rendering-backend details when screenshots, canvas or WebGL differ.

If a ChromeDriver session fails before the page opens, version compatibility is a more immediate suspect than page rendering. If the page opens but pixels differ, keep the version record and continue through the controlled comparison below.

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

Run a controlled headed-versus-headless comparison

Change one condition at a time. A useful comparison uses the same Chrome build and test page in both modes, then keeps the other inputs fixed. The following Python example illustrates the setup with Selenium 4; it is a diagnostic pattern, not a guarantee that every site will become pixel-identical.

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

URL = "https://example.com"


def open_chrome(headless: bool):
    options = Options()
    if headless:
        options.add_argument("--headless=new")
    options.add_argument("--window-size=1365,900")
    driver = webdriver.Chrome(options=options)
    driver.get(URL)
    return driver


for headless in (False, True):
    driver = open_chrome(headless)
    try:
        print("headless:", headless)
        print("URL:", driver.current_url)
        print("viewport:", driver.execute_script(
            "return [window.innerWidth, window.innerHeight, window.devicePixelRatio]"
        ))
        print("title:", driver.title)
        driver.save_screenshot(f"shot-{headless}.png")
    finally:
        driver.quit()

Install Selenium for the Python environment running the test with python -m pip install selenium. The example uses --headless=new because that is the explicit newer-mode argument discussed in Selenium’s migration article; check the documentation for the Chrome version you actually run before using it as a universal recipe. Remove the argument entirely for the headed run. If both runs use different browser installations, profiles or container images, the comparison does not isolate headless mode.

For a fair test, also keep these conditions steady:

  • Use the same URL, account state, cookies, locale, timezone, network path and page data.
  • Set the same viewport dimensions and device scale factor; window dimensions alone do not establish identical raster output.
  • Use the same installed fonts and browser profile, or deliberately use a fresh equivalent profile in each run.
  • Wait for the same meaningful page-readiness condition. A fixed sleep may conceal races; where possible wait for a page-specific element or state.
  • Repeat the run to see whether the difference is consistent or intermittent.

These are controls for debugging, not Chrome guarantees that matching them will force parity.

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

Check the host’s display and GPU path

Headless does not mean every machine takes the same rendering path. Chromium documents that Headless Chrome can use a local GPU in some circumstances, and that GPU activation defers to driver autodetection. On Linux, default OpenGL detection requires an X11 server and a configured DISPLAY; Vulkan has worked on some Linux configurations. See Chromium’s guide to using GPU hardware in Headless Chrome.

If screenshots, canvas or WebGL differ between a workstation and CI, record whether each environment has a display server, the DISPLAY value where relevant, and the GPU/backend information exposed by the browser or host. A Linux container without X11 should not be assumed to render through the same path as a desktop session. Conversely, do not assume every headless run is software-rendered or that adding a GPU flag will fix a mismatch; behavior depends on the available drivers and configuration.

Find the first layer where the runs diverge

Comparing only final screenshots makes it hard to tell whether the cause is navigation, page state, layout or rasterization. Inspect the runs from the outside in:

  1. Navigation: compare the final URL, redirects, page title and browser console or driver logs. A different destination or failed resource changes the rest of the result.
  2. Readiness: check whether the same key element exists and whether the application has reached the same state. The same initial HTML does not necessarily mean asynchronous content has finished loading.
  3. DOM and layout: compare relevant DOM content, computed styles and viewport dimensions. If these already differ, investigate page state, timing, responsive breakpoints or environment inputs before blaming pixel rendering.
  4. Pixels: if the DOM and layout are equivalent but the screenshots differ, focus on fonts, device scale, GPU/backend, antialiasing and other rasterization conditions.

This is a practical debugging sequence, not a Chrome-mandated procedure. It helps distinguish a page that never reached the same state from a page whose final pixels were drawn differently.

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

Common symptoms and what to try

Symptom Likely line of investigation Next check
ChromeDriver cannot start a session Browser/driver compatibility or launch configuration Record both exact versions and verify matching major versions using Selenium’s Chrome documentation.
Content is missing only in one run Navigation, delayed application state, failed resource or inconsistent wait condition Compare final URL, logs, DOM and the same page-specific readiness condition before comparing screenshots.
Layout changes but content is present Viewport, device scale, fonts, locale or responsive behavior Log viewport and device pixel ratio; make page and machine inputs consistent.
Canvas, WebGL or image pixels differ across hosts GPU/backend or display-server differences Record GPU and display setup; on Linux, check X11 and DISPLAY when using default OpenGL detection.
An old headless snippet behaves unexpectedly Legacy implementation or changed defaults across versions Check the Chrome version, Selenium binding and exact argument list against version-specific documentation.

When the mismatch remains, reduce the page to a small reproducible case and include Chrome, ChromeDriver and Selenium versions, operating system/container, launch arguments, viewport and whether GPU rendering was used. Chrome’s Headless documentation directs issue reports to the Chrome project; a minimal case makes an implementation bug easier to separate from differences in the page or host.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If the goal is a website screenshot rather than reproducing a Selenium test, ScreenshotNeo is a website screenshot API and MCP server for developers. A request can return a PNG, JPEG, WebP or PDF; its consent-banner, popup and chat-widget cleanup is separate from Selenium’s browser-mode troubleshooting. It does not replace Selenium when you need to automate interactions or diagnose a particular Chrome installation.

Use a ScreenshotNeo access key in place of YOUR_API_KEY. The API call and option details are in the ScreenshotNeo 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 accepts cookie/consent banners like a visitor and removes 60+ known consent platforms, newsletter popups and chat widgets before capture; each cleanup step can be turned off. Bot checks/CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and responses report page verdict and billing status in headers. Its MCP server provides take_screenshot, get_page_info and capture_pdf tools for AI agents. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

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

Sign up for ScreenshotNeo’s free plan to try 1,000 screenshots a month with no card.

What evidence can—and cannot—establish

The official documentation establishes the implementation history and identifies environment factors that can affect rendering; it does not quantify how often Selenium headless output differs or by how many pixels. The community post titled “Headless chrome doesn’t load content the same way normal chrome does” records one user’s reported symptom, not proof of a universal behavior: Reddit’s r/selenium post.

For a comparison report, state the Chrome and ChromeDriver major versions, old versus unified Headless mode and flags, operating system/display availability, GPU path, and viewport and readiness conditions. Mark the last two as controlled test inputs, not as official guarantees of identical output.

Frequently Asked Questions

Does using --headless=new guarantee the same screenshot as regular Chrome?

No. Unified Headless shares Chrome functionality with regular Chrome, but the available documentation does not promise identical output across every version, host and page.

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

Is there an official percentage for how often Selenium Headless differs?

The cited official sources provide no prevalence statistic or measured size for these differences.

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.