DevToolsActivePort File Doesn't Exist: Causes and Fix
DevToolsActivePort file doesn't exist in Selenium? New ChromeDriver hides it behind other messages. Reproduced on Chrome 128 to 155 in Docker, with fixes.
DevToolsActivePort file doesn't exist means Chrome died before it finished starting, so ChromeDriver had nothing to connect to. In Docker and CI the cause is almost always one of three: Chrome runs as root with the sandbox on, Chrome runs headed with no display, or a second Chrome holds the same profile folder. The fix for the common case is three flags: --headless=new, --no-sandbox (or a non-root user) and --disable-dev-shm-usage. The more useful fix is to read Chrome's own error, which ChromeDriver hides.
This page is part of our Selenium screenshot guide. We reproduced the crash on four ChromeDriver releases and found that the famous message is gone from current versions. That matters, because you may be debugging this error under a different name.
Tested on 2026-10-18 in Docker (OrbStack on macOS,
python:3.12-slim-bookwormlinux/amd64) with Python 3.12, selenium 4.51.0, Debian Chromium and ChromeDriver 155.0.8059.79, and Chrome for Testing 128.0.6613.119, 141.0.7390.122, 148.0.7778.97 and 155.0.8059.79.
What the file is
ChromeDriver starts Chrome with --remote-debugging-port=0. Chrome picks a free port, writes it to DevToolsActivePort inside its user data folder, and ChromeDriver reads the file to open the DevTools connection. If Chrome crashes in its first second, the file never appears. So the message tells you only that Chrome is not running, not why.
The reproduction
The script reads Chrome flags from an environment variable so we could change one thing at a time:
import os import sys from selenium import webdriver from selenium.webdriver.chrome.service import Service opts = webdriver.ChromeOptions() for arg in filter(None, os.environ.get("CHROME_ARGS", "").split(" ")): opts.add_argument(arg) opts.binary_location = "/usr/bin/chromium" service = Service("/usr/bin/chromedriver", log_output=os.environ.get("LOG")) try: driver = webdriver.Chrome(options=opts, service=service) except Exception as exc: print(type(exc).__name__, str(exc).splitlines()[0]) sys.exit(1) try: driver.get("https://example.com") driver.save_screenshot("example.png") print("OK", driver.capabilities["browserVersion"]) finally: driver.quit()
Results with Chromium 155 as root:
CHROME_ARGS |
Result |
|---|---|
| (none): headed, no display, sandbox on | SessionNotCreatedException |
--headless=new |
SessionNotCreatedException |
--no-sandbox (headed, no display) |
SessionNotCreatedException |
--headless=new --user-data-dir=/tmp/prof while another Chrome uses /tmp/prof |
SessionNotCreatedException |
--headless=new --no-sandbox --disable-dev-shm-usage |
OK, 155.0.8059.79 |
A non-root user with --headless=new and the sandbox on also failed, because Docker's default seccomp profile blocks the namespaces the sandbox needs. Our Puppeteer launch failure page shows that case with Chrome's full output.
The message depends on your ChromeDriver version
We ran the same crash (root, headless, sandbox on) against each Chrome for Testing release with its matching driver:
| ChromeDriver | Message you see |
|---|---|
| 128.0.6613.119 | session not created: Chrome failed to start: exited normally. / (session not created: DevToolsActivePort file doesn't exist) / (The process started from chrome location ... is no longer running, so ChromeDriver is assuming that Chrome has crashed.) |
| 141.0.7390.122 | session not created: probably user data directory is already in use, please specify a unique value for --user-data-dir argument, or don't use --user-data-dir |
| 148.0.7778.97 | session not created: Chrome instance exited. Examine ChromeDriver verbose log to determine the cause. |
| 155.0.8059.79 | same as 148 |
The 141 message is misleading: no other Chrome was running and we never set --user-data-dir. If you are on that range and the profile advice does not help, treat it as this crash. Headed Chrome with --no-sandbox and no display gave the same message per version.
Read the real cause
The current message says to examine the verbose log, and it is right. Pass log_output to the Service:
service = Service("/usr/bin/chromedriver", log_output="chromedriver.log")
Then search the log for Chrome's own lines:
grep -i -E 'sandbox|DISPLAY|user data|shm' chromedriver.log
For the root crash, the log held the line ChromeDriver never showed:
ERROR:content/browser/zygote_host/zygote_host_impl_linux.cc:103] Running as root without --no-sandbox is not supported. See https://crbug.com/638180.
Each cause has its own line, so this one grep tells you which fix to apply.
Fixes, by cause
- Root with the sandbox on. Add
--no-sandbox, or better, run as a non-root user with a seccomp profile that allows Chrome's sandbox. Without the sandbox, only the container protects your host from the page; see the Chromium sandbox entry. - No display. Add
--headless=new. If you need a headed browser, start it underxvfb-run. - Profile in use. Give each session its own folder, for example from
tempfile.mkdtemp(), or do not pass--user-data-dir. Kill orphaned Chrome processes left by crashed jobs. - Small
/dev/shm. Add--disable-dev-shm-usageor start the container with--shm-size=1g. We did not trigger this crash in our run, so treat it as a guard, not a proven cause. - Wrong binary. A
binary_locationthat points at a missing or non-executable file also ends here. Check the path in the log.
The working option set from our run:
opts = webdriver.ChromeOptions() opts.add_argument("--headless=new") opts.add_argument("--no-sandbox") opts.add_argument("--disable-dev-shm-usage")
The Chrome flags glossary entry explains what each flag changes.
Symptom, cause, fix
| Symptom | Cause | Fix |
|---|---|---|
| Fails only in Docker, works locally | Root user with sandbox | --no-sandbox or non-root user |
| Fails on a server, works on a laptop | No display, headed mode | --headless=new or Xvfb |
| Fails on the second parallel test | Shared --user-data-dir |
One temp profile per session |
| Fails on heavy pages only | /dev/shm too small |
--disable-dev-shm-usage or --shm-size |
| "user data directory is already in use" with no profile set | ChromeDriver 141-range message for a crash | Read the verbose log |
| "Chrome instance exited" | ChromeDriver 148+ message for a crash | Read the verbose log |
only supports Chrome version N |
Driver and browser mismatch | See session not created |
The same screenshot without Chrome in your container
If Chrome runs in your container only for screenshots, a screenshot API removes the sandbox, display and shared-memory questions together. With the RenderScreenshot Python SDK:
import os from renderscreenshot import Client, TakeOptions client = Client(os.environ["RS_API_KEY"]) image = client.take(TakeOptions.url("https://example.com").wait_for("load")) with open("example.png", "wb") as f: f.write(image)
We did not call the live API for this page. Our post on headless Chrome production failures covers what goes wrong after Chrome starts. Get a free API key to try the request.
Related in this topic
- Selenium Screenshots in Python, Java and C# (Selenium 4) Take a screenshot with Selenium 4 in Python, Java and C#: page, element, exact viewport and PDF. Same test in three languages, timed, with the fixes.
- Selenium Full Page Screenshot: Firefox, Chrome, Stitching Take a full page screenshot in Selenium: Firefox's native call, Chrome via CDP Page.captureScreenshot, or scroll and stitch. Measured limits, times and code.
- Selenium Python Screenshots: save_screenshot Done Right Take a screenshot with Selenium in Python: save_screenshot, headless Chrome, exact window size, WebP output and failure screenshots in pytest. Tested code.
- ChromeDriver: Session Not Created, Version Mismatch Fix Fix 'session not created: this version of ChromeDriver only supports Chrome version N' in Selenium 4, reproduced in Docker with a tested Python fix.
- Puppeteer: Failed to Launch the Browser Process (Fixed) Failed to launch the browser process in Puppeteer, step by step: we hit four different launch errors in one Docker image on Puppeteer 25 and fixed each one.
- Puppeteer: Navigation Timeout of 30000 ms Exceeded Navigation timeout of 30000 ms exceeded in Puppeteer has four common causes. We reproduced three on Puppeteer 25 and show a tested fix for all four.