Root Cause Diagnosis
This error means ChromeDriver successfully launched the Chrome binary, but Chrome crashed or exited before it could open the DevTools debugging port that ChromeDriver polls to confirm a session started. ChromeDriver doesn’t report why Chrome died — it only knows the expected port file (DevToolsActivePort) inside the user-data directory never got written. The two dominant causes are: Chrome running as root/administrator with no --no-sandbox flag (the sandbox refuses to initialize under root), and insufficient /dev/shm space in containerized environments (Docker, CI runners), which causes the renderer process to crash on startup.
Quick Fix
Add these three flags to your ChromeOptions before creating the driver:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
options.add_argument("--headless=new")
driver = webdriver.Chrome(options=options)
This resolves the majority of cases in under a minute, particularly in Docker containers and CI pipelines (GitHub Actions, GitLab CI, Jenkins).
Step-by-Step Resolution
1. Confirm you’re not running as root without sandbox flags.
If your process user is root (common in Docker base images), Chrome’s sandbox will refuse to start:
# In your Dockerfile — create and use a non-root user
RUN useradd -m seluser
USER seluser
If switching users isn’t feasible, --no-sandbox is the accepted workaround (see Edge Cases below for the trade-off).
2. Increase or bypass shared memory in containers.
Docker’s default /dev/shm is 64 MB, which is too small for Chrome’s rendering process:
docker run --shm-size=2g your-image
Or, if you can’t change container run parameters, keep --disable-dev-shm-usage in your options so Chrome writes to /tmp instead of /dev/shm.
3. Verify Chrome and ChromeDriver versions are matched.
A version skew between the installed Chrome binary and ChromeDriver is the second most common trigger, especially after unattended Chrome auto-updates.
google-chrome --version
chromedriver --version
If using webdriver-manager or Selenium Manager (built into Selenium 4.6+), let it resolve the matching driver automatically instead of pinning a static binary:
# Selenium 4.6+ resolves the correct driver automatically — no explicit Service needed
driver = webdriver.Chrome(options=options)
4. Kill orphaned Chrome/ChromeDriver processes holding the user-data directory.
A leftover lock file from a previous crashed session blocks new sessions from claiming the same profile path:
pkill -f chrome
pkill -f chromedriver
rm -rf /tmp/.com.google.Chrome.*
5. Specify a unique, writable user-data directory per session.
Concurrent test runs sharing a default profile path race for the same lock file:
import uuid
options.add_argument(f"--user-data-dir=/tmp/chrome-{uuid.uuid4()}")
6. Check available system memory.
Chrome’s renderer process needs headroom beyond what your test framework itself consumes:
free -h
Under 500 MB free on a CI runner or small VPS is a frequent silent cause — the OOM killer terminates the Chrome process before it can write the DevTools port file. Check dmesg | grep -i "oom\|killed process" to confirm.
7. Rule out a corrupted Chrome installation.
apt-get remove --purge google-chrome-stable
apt-get install google-chrome-stable
Why This Fails for Some Users
- GitHub Actions / GitLab CI default runners: shared runners often have
/dev/shmcapped low and limited RAM, so--disable-dev-shm-usagecombined with--no-sandboxis close to mandatory, not optional, on these platforms. - Apple Silicon (M1/M2/M3) Docker images: ARM-based images pulling an x86 Chrome binary under emulation frequently crash silently at startup; use an ARM-native Chromium build or
--platform=linux/amd64explicitly if emulation is unavoidable. - Headless Electron-based test wrappers: apps embedding Chromium (Electron, CEF) sometimes never expose the DevTools port the same way stock Chrome does, so this specific fix set doesn’t apply — the underlying binary needs
--remote-debugging-portset explicitly. - Windows with antivirus/EDR software: some enterprise endpoint protection tools quarantine or delay the Chrome process on launch, causing ChromeDriver’s timeout to fire before the port file is written even though Chrome eventually starts.
- Corporate proxy or certificate-pinning environments: Chrome can hang during startup trying to reach a blocked update-check or Safe Browsing endpoint; add
--disable-background-networkingand--disable-client-side-phishing-detectionin locked-down networks. - Selenium Grid / remote WebDriver setups: the error can originate on the Grid node rather than the client, so
--no-sandbox/--disable-dev-shm-usagemust be set in the node’s container config, not just the client-side test code — client-side flags alone won’t fix it.