Recommended Free Tools
There is no single current “Headless Chrome” User-Agent string. Older Headless Chrome builds commonly exposed a HeadlessChrome/<version> token, but modern Chrome’s --headless mode uses the same browser implementation as headful Chrome. Since Chrome 132, the former implementation is distributed separately as chrome-headless-shell. The value you receive depends on the Chrome version, operating system, headless implementation, User-Agent reduction, and any override configured by your automation client.
For reliable automation or bot analysis, inspect the actual request and User-Agent Client Hints (UA-CH) in the target environment. Treat a literal HeadlessChrome match as a historical clue, not a complete detector.
What a User-Agent header tells a server
Chromium defines the User-Agent request header as “a characteristic string that allows servers and network peers to identify the application, operating system, vendor, and/or version of the requesting user agent.” Browsers send it with HTTP requests; JavaScript can also read a related value through navigator.userAgent.
A typical reduced desktop Chrome value resembles:
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36
The exact operating-system tokens, Chrome version, architecture details and formatting vary. Chrome’s User-Agent Reduction project began rolling out reduced desktop strings in Chrome 107 to limit passive fingerprinting. Applications that need additional platform or version detail should use UA-CH instead of assuming every detail is present in the raw string.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minute#1 Best Overall
Historical HeadlessChrome strings
The legacy example
Google’s legacy Headless documentation showed a value containing:
HeadlessChrome/60.0.3082.0
That is a historical example from the old Headless implementation, not a universal value for current Chrome. A server may still encounter the token when a client uses the standalone legacy shell or explicitly supplies a matching custom string.
Why copying one string fails
Hard-coding one “current Headless UA” is unsafe because Chrome versions, platforms, launch modes and overrides differ. Even when two sessions run the same Chrome release, their headers can differ because of a custom User-Agent, a proxy, a Selenium or Puppeteer setting, or reduced-UA behavior.
How Headless Chrome works today
Unified headless mode
Google’s current documentation states: “Chrome now has unified Headless and headful modes.” The modern --headless flag runs the real Chrome browser without displaying a normal window. Its networking and rendering implementation is shared with headful Chrome, so the default UA does not need to advertise a separate “headless” product.
Free tools Windows power users keep installed
One-click scans. No signup required.
The Chrome 112 and Chrome 132 boundaries
- Chrome 112 made the new unified Headless mode available.
- From Chrome 132.0.6793.0, the old implementation is no longer part of the normal Chrome binary. Google says it is available as a standalone
chrome-headless-shellbinary from the Chrome for Testing dashboard. - On Chrome 132 and later,
--headless=oldprints an error.--headlessand--headless=newrun the unified mode.
Consequently, a modern headless session can send an ordinary Chrome UA, while a legacy shell or an explicit override can expose HeadlessChrome.
Where to observe the value
HTTP request header
The server-side value is the User-Agent request header. Log it at the edge or in your application before making any classification decision.
JavaScript-visible value
Pages can read:
console.log(navigator.userAgent);
Compare this with the actual HTTP header during testing. A proxy, browser extension, automation library or override can make the two surfaces differ.
Rank #2
User-Agent Client Hints
UA-CH exposes structured browser and platform information through low- and high-entropy hints, subject to permission and server negotiation. The reduced UA may intentionally omit details that older parsers expect. Code that needs full platform or version information should migrate to UA-CH and handle reduced strings gracefully rather than treating a missing token as proof of headless operation.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Inspecting Headless Chrome with automation clients
Command-line observation
Start the same Chrome binary in the mode you deploy and inspect a request at your own endpoint or browser devtools. For example:
google-chrome --headless --no-sandbox --dump-dom https://example.com
The command does not print the request header itself; use server logs, a request-inspection endpoint, or DevTools Protocol network events to observe the emitted value.
Puppeteer: read and override the UA
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({headless: true});
const page = await browser.newPage();
console.log('Default UA:', await page.evaluate(() => navigator.userAgent));
await page.setUserAgent({
userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36',
userAgentMetadata: {
brands: [
{brand: 'Chromium', version: '132'},
{brand: 'Not_A Brand', version: '99'}
],
fullVersion: '132.0.0.0',
platform: 'Linux',
platformVersion: '6.8.0',
architecture: 'x86',
model: '',
mobile: false
}
});
console.log('Overridden UA:', await page.evaluate(() => navigator.userAgent));
await browser.close();
Metadata support and option names can vary with Puppeteer and the underlying Chrome version. Test both request headers and JavaScript-visible values after an override.
Selenium: set a command-line value
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('--headless')
options.add_argument('--user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36')
driver = webdriver.Chrome(options=options)
try:
print(driver.execute_script('return navigator.userAgent'))
finally:
driver.quit()
This changes the string, but it does not automatically make every related UA-CH value consistent. For controlled testing, use DevTools Protocol metadata overrides as well.
Overriding the UA correctly with DevTools Protocol
The Chrome DevTools Protocol method Emulation.setUserAgentOverride accepts a UA string and an optional userAgentMetadata object. The protocol reference specifies that userAgentMetadata must be set for Client Hint headers to be sent.
const client = await page.target().createCDPSession();
await client.send('Emulation.setUserAgentOverride', {
userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36',
userAgentMetadata: {
brands: [{brand: 'Chromium', version: '132'}],
fullVersion: '132.0.0.0',
platform: 'Linux',
platformVersion: '6.8.0',
architecture: 'x86',
model: '',
mobile: false
}
});
Keep the low-entropy UA, metadata brands, full version, platform and mobile flag internally consistent. Then verify a real navigation: inspect the HTTP request, navigator.userAgent, navigator.userAgentData, and any Sec-CH-UA* headers your server receives.
Rank #3
Can you detect Headless Chrome from the UA?
Why a literal match is weak
Checking whether the string contains HeadlessChrome can identify some old shell sessions, but it misses modern unified headless sessions and can be defeated by an override. User-Agent reduction also removes passive details that old parsers may expect.
A better multi-signal approach
- Record the raw HTTP UA and relevant UA-CH headers.
- Compare the header values with JavaScript-visible values.
- Use browser and protocol behavior only as supporting evidence, not as a single definitive flag.
- Version your rules: a signal that worked for a pre-132 legacy shell should not be silently applied to unified Chrome.
- Allow for legitimate automation, accessibility tools, testing systems and privacy software before blocking.
No single passive value proves that a browser is headless. Detection should be risk-based, continuously tested against the Chrome versions and launch configurations you actually encounter.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesCommon problems and fixes
“My script expected HeadlessChrome, but it is missing”
You are probably using unified headless Chrome. Check the Chrome version and launch mode, then inspect the live header instead of assuming a token. If you specifically require legacy behavior, use the separately distributed chrome-headless-shell and document that dependency.
“The UA header and navigator.userAgent disagree”
Look for a proxy, extension, automation-library setting or partial override. Capture a request trace and read the page value in the same session. Apply the override through one control path and retest.
“UA-CH headers are absent after an override”
Supply userAgentMetadata to Emulation.setUserAgentOverride. The DevTools Protocol requires metadata for Client Hint headers. Also ensure the server requests the hints where appropriate and that your browser version supports the fields you use.
“--headless=old fails on Chrome 132 or newer”
That flag was removed from the regular Chrome binary. Use --headless or --headless=new for unified mode, or install the standalone chrome-headless-shell when legacy compatibility is genuinely required.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
“My parser breaks on reduced UA strings”
Stop extracting architecture or detailed version data from fixed string positions. Parse the stable portions defensively and use UA-CH for details, with a fallback path when hints are unavailable.
Rank #4
Practical testing checklist
- Record the exact Chrome version, operating system, binary (
chromeorchrome-headless-shell) and launch flags. - Capture the server’s
User-Agentheader during a real navigation. - Read
navigator.userAgentand, when available,navigator.userAgentData. - Test with no override and with the override used in production.
- Check both unified headless and a visible session of the same Chrome release.
- Exercise reduced-UA and missing-UA-CH cases in your parser tests.
Automated screenshots without managing a browser
Or skip the browser setup
If your goal is simply to capture a page rather than study Chrome identity, ScreenshotNeo provides a website screenshot API and MCP server. A single request returns PNG, JPEG, WebP or PDF, while the service accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing result.
cURL (see 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
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}`);
ScreenshotNeo also exposes an MCP server for Claude, Cursor and other MCP clients, with take_screenshot, get_page_info and capture_pdf tools. Every plan includes its features; 1,000 screenshots per month are free with no card, Starter is $5 for 3,000, and paid plans start at that $5 level. Create a free ScreenshotNeo account.
Bottom line
“Headless Chrome UA” describes a changing implementation detail, not one permanent string. HeadlessChrome/<version> belongs chiefly to historical or explicitly legacy sessions. Modern unified headless Chrome can look like ordinary Chrome, so inspect live headers, use UA-CH for structured details, and combine multiple signals when detection matters.
Frequently Asked Questions
Does every headless Chrome request contain HeadlessChrome?
No. Modern unified headless Chrome generally uses the normal Chrome implementation and may send an ordinary reduced UA. The token is mainly a legacy or explicitly overridden signal.
What replaced the old headless implementation after Chrome 132?
The regular Chrome binary uses unified headless mode. The old implementation is available separately as the chrome-headless-shell binary.
Should I block requests whose UA contains HeadlessChrome?
Not by itself. Combine UA and UA-CH data with other, version-aware signals and account for legitimate automation.
How can I make an override consistent?
Set the UA string and matching userAgentMetadata through DevTools Protocol, then verify request headers and JavaScript-visible values in a real navigation.
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.




