Before submitting
Area
apps/server
Summary
Tabs in the environment-hosted browser identify themselves as an automated headless browser, so ordinary sites refuse to serve them. This affects every tab of a server without an attached desktop app, such as a remote server opened from the desktop app, the web app, or mobile.
https://www.cnn.com/ shows only Unknown Error. Google search redirects to its "unusual traffic" captcha. In the browser panel this looks like broken links: you click a link and get an error page or a captcha.
Steps to reproduce
- Run a T3 server that no desktop app is attached to, such as
t3 serve on a Linux machine. Connect to it from the desktop app or the web app.
- Open the Browser panel in a thread on that environment. The tab reports
runtime: "server".
- Go to
https://www.cnn.com/.
- Go to
https://www.google.com/search?q=electron+webview.
Expected behavior
Both pages load as they do in Chrome on the same machine and network.
Actual behavior
- CNN returns HTTP 200 with a 13-byte body,
Unknown Error, from its Fastly/Varnish cache.
- Google redirects to
/sorry/index ("Our systems have detected unusual traffic from your computer network") with a reCAPTCHA.
Inside the tab, navigator.userAgent is Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/154.0.8037.92 Safari/537.36. navigator.userAgentData.brands includes HeadlessChrome, and navigator.webdriver is true.
Root cause
ServerBrowserContexts launches the pinned chrome-headless-shell through Playwright and creates contexts with only a viewport and a scale factor (launch options, context options). That leaves two automation signals in place:
- The headless identity. The shell's default user agent and client-hint brands both say
HeadlessChrome.
- The webdriver flag. Chrome sets
navigator.webdriver = true in headless mode on its own. Playwright 1.60 does not pass --enable-automation, and the launch arguments don't contain it. Only --disable-blink-features=AutomationControlled clears the flag.
Sites check different signals. To isolate them, I drove the same chrome-headless-shell 154.0.8037.92 binary with Playwright, from the same machine and IP, in five configurations:
| Configuration |
CNN |
Google search |
DuckDuckGo |
| Current behavior |
Unknown Error |
captcha |
loads |
User-agent string without Headless, brands unchanged |
loads |
captcha |
blocked (418 page) |
User agent and brands set consistently through Emulation.setUserAgentOverride |
loads |
captcha |
loads |
Webdriver flag off only (--disable-blink-features=AutomationControlled) |
Unknown Error |
captcha |
loads |
| Consistent user agent and brands, webdriver flag off |
loads |
loads |
loads |
So CNN keys on the HeadlessChrome user agent and Google needs both signals gone. DuckDuckGo shows that changing only the user-agent string makes things worse: a user agent that disagrees with Sec-CH-UA gets blocked. A fix needs to change both together.
The brands can't be fixed with launch flags. A --user-agent flag changes the user-agent string, but chrome-headless-shell still reports HeadlessChrome in navigator.userAgentData.brands and Sec-CH-UA, so DuckDuckGo still returns its 418 page. The brand list is built into the shell. Adding UserAgentClientHint to --disable-features had no effect. CDP's Emulation.setUserAgentOverride with userAgentMetadata does set both (third row above), but it applies per target, so every page, popup, and worker would need it.
Full Google Chrome in headless mode is different: it already reports the normal Chromium/Google Chrome brands. Only its user-agent string says HeadlessChrome. I ran the same binary-level comparison against more sites, all from the same machine and IP:
| Site |
chrome-headless-shell today |
Google Chrome 154 headless, --user-agent without Headless, AutomationControlled off |
| CNN |
Unknown Error |
loads |
| Google search |
captcha |
loads |
| OpenAI Platform (Cloudflare, as in #16596) |
403 Just a moment... |
loads |
| NYT |
403 |
loads |
| Stack Overflow |
Cloudflare "Performing security verification" |
loads |
| Reddit |
"You've been blocked by network security" |
"Prove your humanity" challenge |
| DuckDuckGo, Bing, Amazon |
load |
load |
Workaround for operators: replace ~/.t3/tools/chrome-headless-shell/<platform>/<version>/chrome-headless-shell with a script that runs /usr/bin/google-chrome with the same arguments, plus --user-agent=…Chrome/<major>.0.0.0… and --disable-blink-features=AutomationControlled. T3 only checks that this path is an executable file, so it launches the script. I'm running this on the affected server. Tabs launched through T3 report normal Chrome (webdriver: false, Google Chrome brands), and CNN and Google search load in the browser panel. It has to be reapplied whenever T3 installs a new pinned shell version.
This is not a request to defeat captchas or bot checks. The tab is driven by a human in the browser panel, and the user is the person the site would serve in Chrome. The tab presents as automated only because of how T3 launches its shell.
Impact
Major degradation or frequent failure
Version or commit
T3 Code 0.0.46-nightly.20261006.2735. Code references are at 72d5c32ba6.
Environment
The server is t3 serve as a systemd user service on Ubuntu 26.04 (x86_64), using T3's bundled chrome-headless-shell 154.0.8037.92. The client is the T3 Code (Nightly) desktop app on macOS 26, connected to that server remotely.
Before submitting
Area
apps/server
Summary
Tabs in the environment-hosted browser identify themselves as an automated headless browser, so ordinary sites refuse to serve them. This affects every tab of a server without an attached desktop app, such as a remote server opened from the desktop app, the web app, or mobile.
https://www.cnn.com/shows onlyUnknown Error. Google search redirects to its "unusual traffic" captcha. In the browser panel this looks like broken links: you click a link and get an error page or a captcha.Steps to reproduce
t3 serveon a Linux machine. Connect to it from the desktop app or the web app.runtime: "server".https://www.cnn.com/.https://www.google.com/search?q=electron+webview.Expected behavior
Both pages load as they do in Chrome on the same machine and network.
Actual behavior
Unknown Error, from its Fastly/Varnish cache./sorry/index("Our systems have detected unusual traffic from your computer network") with a reCAPTCHA.Inside the tab,
navigator.userAgentisMozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/154.0.8037.92 Safari/537.36.navigator.userAgentData.brandsincludesHeadlessChrome, andnavigator.webdriveristrue.Root cause
ServerBrowserContextslaunches the pinnedchrome-headless-shellthrough Playwright and creates contexts with only a viewport and a scale factor (launch options, context options). That leaves two automation signals in place:HeadlessChrome.navigator.webdriver = truein headless mode on its own. Playwright 1.60 does not pass--enable-automation, and the launch arguments don't contain it. Only--disable-blink-features=AutomationControlledclears the flag.Sites check different signals. To isolate them, I drove the same
chrome-headless-shell154.0.8037.92 binary with Playwright, from the same machine and IP, in five configurations:Unknown ErrorHeadless, brands unchangedEmulation.setUserAgentOverride--disable-blink-features=AutomationControlled)Unknown ErrorSo CNN keys on the
HeadlessChromeuser agent and Google needs both signals gone. DuckDuckGo shows that changing only the user-agent string makes things worse: a user agent that disagrees withSec-CH-UAgets blocked. A fix needs to change both together.The brands can't be fixed with launch flags. A
--user-agentflag changes the user-agent string, but chrome-headless-shell still reportsHeadlessChromeinnavigator.userAgentData.brandsandSec-CH-UA, so DuckDuckGo still returns its 418 page. The brand list is built into the shell. AddingUserAgentClientHintto--disable-featureshad no effect. CDP'sEmulation.setUserAgentOverridewithuserAgentMetadatadoes set both (third row above), but it applies per target, so every page, popup, and worker would need it.Full Google Chrome in headless mode is different: it already reports the normal
Chromium/Google Chromebrands. Only its user-agent string saysHeadlessChrome. I ran the same binary-level comparison against more sites, all from the same machine and IP:--user-agentwithoutHeadless,AutomationControlledoffUnknown ErrorJust a moment...Workaround for operators: replace
~/.t3/tools/chrome-headless-shell/<platform>/<version>/chrome-headless-shellwith a script that runs/usr/bin/google-chromewith the same arguments, plus--user-agent=…Chrome/<major>.0.0.0…and--disable-blink-features=AutomationControlled. T3 only checks that this path is an executable file, so it launches the script. I'm running this on the affected server. Tabs launched through T3 report normal Chrome (webdriver: false,Google Chromebrands), and CNN and Google search load in the browser panel. It has to be reapplied whenever T3 installs a new pinned shell version.This is not a request to defeat captchas or bot checks. The tab is driven by a human in the browser panel, and the user is the person the site would serve in Chrome. The tab presents as automated only because of how T3 launches its shell.
Impact
Major degradation or frequent failure
Version or commit
T3 Code
0.0.46-nightly.20261006.2735. Code references are at72d5c32ba6.Environment
The server is
t3 serveas a systemd user service on Ubuntu 26.04 (x86_64), using T3's bundledchrome-headless-shell154.0.8037.92. The client is the T3 Code (Nightly) desktop app on macOS 26, connected to that server remotely.