What Undetected Chromedriver Actually Does

Stock ChromeDriver gives itself away in two places. It injects JavaScript variables prefixed with cdc_ into every page, and it starts Chrome with --enable-automation, which sets navigator.webdriver to true.
Undetected chromedriver overwrites the code block that injects those variables, then launches Chrome as its own subprocess with a remote debugging port and attaches ChromeDriver through debuggerAddress. Chrome never receives the automation flag, so navigator.webdriver stays false with no JavaScript overrides.
It does not hide your IP, and the maintainer says so in capital letters on the package page. It does not touch canvas, WebGL, or TLS fingerprints, rotate user agents, or simulate mouse movement.
Where the Project Stands in 2026

The last release, 3.5.5, shipped on February 17, 2024. Nothing has followed, the author now points everyone to nodriver, and the package still pulls around 1.7 million PyPI downloads a month.
The PyPI build imports distutils, which Python 3.12 removed, so it fails to import there. The GitHub master branch has the fix.
How to Install and Run It

- Install Chrome and put it on your PATH.
- Run
pip install undetected-chromedriveron Python 3.11 or older. On 3.12 or newer, install from master. - Run the script below and confirm the title prints.
pip install git+https://github.com/ultrafunkamsterdam/undetected-chromedriver@masterimport undetected_chromedriver as uc
driver = uc.Chrome(use_subprocess=True)
driver.get("https://nowsecure.nl")
print(driver.title)
driver.quit()use_subprocess=True is already the default and, per the maintainer, stopped affecting detection around Chrome 104, so ignore guides that flip it for stealth. The rest is plain Selenium, since uc.Chrome subclasses the Chrome WebDriver.
Also Read: Plug Proxyon Into Selenium
Pinning Your Chrome Version

The most common failure is a SessionNotCreatedException from a version mismatch. The patcher never reads your installed Chrome. It downloads the latest stable build listed by Chrome for Testing, which often runs ahead of what your machine has installed.
driver = uc.Chrome(version_main=142)Match the number to the major version at chrome://settings/help and bump it when you update Chrome.
Undetected Chromedriver Proxy Setup

Proxies go in through Chrome's own --proxy-server flag:
import undetected_chromedriver as uc
options = uc.ChromeOptions()
options.add_argument("--proxy-server=http://proxy_host:port")
driver = uc.Chrome(options=options, version_main=142)Chrome ignores credentials embedded in that flag. http://user:pass@host:port raises no error, it just drops the login, and at least one top-ranking guide ships that snippet as working code. The fix is IP whitelisting: authorize your server's IP with the provider and pass only host:port. Run it through the proxy formatter if you are unsure of the format.
Chrome takes one proxy per browser instance and cannot swap it mid-session, so use a rotating gateway or run separate instances on sticky sessions. The IP decides your success rate: residential proxies for protected targets, datacenter proxies for sites that only inspect the browser.
Headless Mode
Headless is officially unsupported. uc.Chrome(headless=True) adds --headless=new, and the new headless mode still reports HeadlessChrome in the user agent, a string the library only rewrites conditionally.
On a Linux server, run headed inside a virtual display instead. Xvfb gives you a real window nobody sees:
sudo apt install xvfb
xvfb-run python scraper.pyMaintained Alternatives
For anything new in 2026, start with nodriver. It is the same author's successor, drops Selenium and the ChromeDriver binary, and speaks to Chrome over CDP with an async API, so there is no patched binary to break. SeleniumBase UC Mode is the maintained option if you must stay on Selenium. Either way, a maintained browser on a flagged datacenter IP still gets blocked.
Also Read: Sticky Sessions vs Rotating Proxies
FAQ Section

Is undetected chromedriver still maintained?
No. The last release was 3.5.5 in February 2024. The repository is still online and the package still installs, but there have been no fixes since, and the author has moved to nodriver.
Why does undetected chromedriver fail on Python 3.12?
The PyPI release imports distutils, which Python 3.12 removed. Install from the GitHub master branch, which replaced that import with packaging.
Does undetected chromedriver hide my IP address?
No. It only changes how ChromeDriver and Chrome present themselves to the page. Your real IP reaches the target unless you add a proxy with the --proxy-server flag.
Does undetected chromedriver work with Cloudflare?
It passes the basic JavaScript challenge on many Cloudflare sites when run headed from a clean IP. It does not solve Turnstile or any other CAPTCHA, and heavily protected targets can still block it on IP reputation alone.
Can I use undetected chromedriver with authenticated proxies?
Not through --proxy-server, since Chrome drops the username and password. Whitelist your server IP with the proxy provider instead, or load a small Chrome extension that answers the proxy auth challenge, which the maintainer warns can lower undetectability.
Final Thoughts
Undetected chromedriver is still a reasonable pick when you have an existing Selenium codebase, a target that only checks WebDriver signals, and a clean IP to run from. It is the wrong pick for new projects, Python 3.12 without the master install, or headless at scale, where nodriver is the better starting point. With either one, the IP does more work than the patch.