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.
session not created: This version of ChromeDriver only supports Chrome version N means the ChromeDriver binary and the Chrome binary on the machine have different major versions. The second line of the error tells you both numbers. With Selenium 4.6 or later, the fix is usually to delete code and files: remove the hard-coded driver path and the old chromedriver on PATH, and let Selenium Manager pick the matching driver.
This page belongs to our Selenium screenshot guide. We reproduced the error in three version pairs, traced where the stale driver came from, and tested the fix in Python. Java code follows the same pattern; we list what we could not run.
Tested on 2026-10-18 in Docker (
python:3.12-slim-bookworm, linux/amd64) with Python 3.12, selenium 4.51.0, Chrome for Testing 128.0.6613.119, 148.0.7778.97 and 155.0.8059.79, and Debian's Chromium 155.0.8059.79.
Reproducing the error
The script below pins a driver path and a browser path, the way most old tutorials did. We then paired drivers and browsers from different Chrome for Testing releases.
import sys from selenium import webdriver from selenium.webdriver.chrome.service import Service chrome_path, driver_path = sys.argv[1], sys.argv[2] opts = webdriver.ChromeOptions() opts.add_argument("--headless=new") opts.add_argument("--no-sandbox") opts.binary_location = chrome_path driver = webdriver.Chrome(options=opts, service=Service(driver_path)) try: driver.get("https://example.com") driver.save_screenshot("example.png") finally: driver.quit()
Results from the run:
| ChromeDriver | Chrome | Result |
|---|---|---|
| 128.0.6613.119 | 155.0.8059.79 | This version of ChromeDriver only supports Chrome version 128 / Current browser version is 155.0.8059.79 with binary path ... |
| 148.0.7778.97 | 155.0.8059.79 | ... only supports Chrome version 148 / Current browser version is 155.0.8059.79 ... |
| 155.0.8059.79 | 148.0.7778.97 | ... only supports Chrome version 155 / Current browser version is 148.0.7778.97 ... |
| 155.0.8059.84 (Selenium Manager) | 155.0.8059.79 | OK |
Two things to read from this. The check is on the major version only: a driver build .84 worked with browser build .79. And the error is symmetric: an older Chrome with a newer driver fails the same way. That second case shows up when a server pins Chrome with apt-mark hold while the driver comes from a newer download.
Where the stale driver comes from
Every mismatch we have seen has one of these sources. Check them in this order.
- A path in code.
Service("/usr/local/bin/chromedriver")orexecutable_path=in old code always wins. Search the codebase forchromedriver. - A binary on
PATH. Runwhich -a chromedriverandchromedriver --version. Selenium checksPATHbefore it downloads anything. - A Docker layer. A Dockerfile that downloads a driver once is cached. When the base image later brings a newer Chrome, the old driver layer stays.
- A wrapper library.
webdriver-managerand similar packages keep their own caches and can lag behind Chrome. - A second Chrome. The driver matches Chrome A, but
binary_locationor the system default points to Chrome B. The error's "binary path" shows which one was used.
What Selenium Manager does with an old driver on PATH
We put ChromeDriver 128 first on PATH, removed the Service path from the code, and pointed the browser at Chrome 155. Selenium 4.51.0 printed this warning, used the old driver anyway, and failed:
The chromedriver version (128.0.6613.119) detected in PATH at /opt/128.0.6613.119/chromedriver-linux64/chromedriver might not be compatible with the detected chrome version (155.0.8059.79); currently, chromedriver 155.0.8059.84 is recommended for chrome 155.*, so it is advised to delete the driver in PATH and retry
So the warning names the exact fix. Many logs bury it above the stack trace, so search for "recommended for chrome" in CI output.
The tested fix (Python)
With no driver on PATH and no Service path, Selenium Manager resolved a matching driver. This ran in the same container:
from selenium import webdriver opts = webdriver.ChromeOptions() opts.add_argument("--headless=new") opts.add_argument("--no-sandbox") opts.binary_location = "/usr/bin/chromium" driver = webdriver.Chrome(options=opts) # no Service path: Selenium Manager picks the driver try: caps = driver.capabilities print("browser", caps["browserVersion"], "driver", caps["chrome"]["chromedriverVersion"].split(" ")[0]) driver.get("https://example.com") driver.save_screenshot("example.png") finally: driver.quit()
Output: browser 155.0.8059.79 driver 155.0.8059.84. Print both versions at start-up like this in production; it turns the next mismatch into a one-line log entry instead of a stack trace. --no-sandbox is there because the container runs as root; the DevToolsActivePort page explains that trade-off.
If your network blocks downloads at runtime, pin instead of resolving: install Chrome for Testing and ChromeDriver of the same version in the image (for example with npx @puppeteer/browsers install [email protected] and [email protected]), and pass both paths.
The same fix in Java
Selenium Java 4.6+ includes the same Selenium Manager. Remove System.setProperty("webdriver.chrome.driver", ...) and any ChromeDriverService built with a fixed path:
import org.openqa.selenium.OutputType; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; import java.nio.file.Files; import java.nio.file.Path; public class Shot { public static void main(String[] args) throws Exception { ChromeOptions options = new ChromeOptions(); options.addArguments("--headless=new"); ChromeDriver driver = new ChromeDriver(options); // Selenium Manager resolves the driver try { driver.get("https://example.com"); byte[] png = driver.getScreenshotAs(OutputType.BYTES); Files.write(Path.of("example.png"), png); } finally { driver.quit(); } } }
We did not run the Java listing: the test machine had no JDK installed on the test date. The class and method names are from the Selenium Java API.
Symptom, cause, fix
| Symptom | Likely cause | Fix |
|---|---|---|
only supports Chrome version N, browser newer |
Chrome updated, driver pinned | Remove the pinned path; let Selenium Manager resolve |
only supports Chrome version N, browser older |
Chrome held back, driver newer | Pin both to one Chrome for Testing version |
| Warning "might not be compatible", then the error | Old driver on PATH |
Delete it or remove it from PATH |
| Works locally, fails in CI | CI image has a different Chrome | Print browser and driver versions at start |
Fails after docker build with cache |
Old driver layer reused | Rebuild without cache; pin versions together |
| Error names an unexpected binary path | Two Chrome installs | Set binary_location explicitly |
Chrome instance exited instead |
Chrome started and crashed | See DevToolsActivePort file doesn't exist |
The same screenshot without a driver
A screenshot API removes the driver and the browser from your machine, so there is nothing to keep in step. 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").full_page()) with open("example.png", "wb") as f: f.write(image)
The Java SDK has the same take and TakeOptions calls, shown end to end in the Java screenshot API guide. We did not call the live API for this page. If you only use Selenium to take screenshots, not to test flows, a free API key replaces this whole class of error.
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.
- 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.
- 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.