Making WebDriver Requests Without Specifying a Debugger Address
Start a fresh ChromeDriver session without debuggerAddress, understand remote debugging limits, and fix unsupported-operation errors.
For a normal local Selenium Chrome session, omit debuggerAddress. Create Chrome options and pass them to ChromeDriver. ChromeDriver will launch a new browser and own the session.
debuggerAddress is only needed when you want ChromeDriver to attach to a Chrome process that is already running with a DevTools debugging server. That attached mode can lack commands that depend on ChromeDriver’s startup automation extension. A Selenium Grid URL is a different value: it is the remote WebDriver server endpoint, not a debugger address.
Choose the session model first
| Goal | What to configure | Browser ownership |
|---|---|---|
| Start a new local Chrome | Chrome options only | ChromeDriver launches and controls Chrome |
| Attach to an existing Chrome | debuggerAddress such as 127.0.0.1:9222 |
Chrome was started separately |
| Run on Selenium Grid | Grid URL plus browser options | A remote WebDriver server launches the browser |
The ChromeDriver capability reference defines debuggerAddress as the host and port of a Chrome debugger server. Selenium’s Chrome documentation shows the ordinary options-based constructor without that capability. Selenium’s Remote WebDriver documentation requires a Grid URL and an options instance. See the ChromeDriver capabilities reference, Selenium Chrome documentation, and Selenium Remote WebDriver documentation.
Start a fresh local Chrome session
Python
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
# Add normal Chrome arguments here if needed, for example:
# options.add_argument("--headless=new")
# options.add_argument("--window-size=1440,900")
driver = webdriver.Chrome(options=options)
try:
driver.get("https://example.com")
print(driver.title)
finally:
driver.quit()
Java
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class FreshChrome {
public static void main(String[] args) {
ChromeOptions options = new ChromeOptions();
// options.addArguments("--headless=new");
// options.addArguments("--window-size=1440,900");
WebDriver driver = new ChromeDriver(options);
try {
driver.get("https://example.com");
System.out.println(driver.getTitle());
} finally {
driver.quit();
}
}
}
Node.js
import { Builder } from "selenium-webdriver";
import chrome from "selenium-webdriver/chrome.js";
const options = new chrome.Options();
// options.addArguments("--headless=new");
// options.addArguments("--window-size=1440,900");
const driver = await new Builder()
.forBrowser("chrome")
.setChromeOptions(options)
.build();
try {
await driver.get("https://example.com");
console.log(await driver.getTitle());
} finally {
await driver.quit();
}
C#
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
var options = new ChromeOptions();
// options.AddArgument("--headless=new");
// options.AddArgument("--window-size=1440,900");
using IWebDriver driver = new ChromeDriver(options);
driver.Navigate().GoToUrl("https://example.com");
Console.WriteLine(driver.Title);
What you should remove from an existing configuration
Delete the capability assignment and keep the rest of your browser options:
# Remove this for a new local session:
# options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
# Keep ordinary options:
options.add_argument("--headless=new")
options.add_argument("--disable-gpu")
In Selenium 4, browser-specific options classes are the supported way to provide capabilities. Do not put a debugger address in a request header and do not use it as a replacement for a Grid URL.
When attaching to an existing Chrome is intentional
Use this only when another process owns the browser and has started Chrome with remote debugging enabled. The address is the debugger host and port, not a WebDriver server URL.
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
driver = webdriver.Chrome(options=options)
try:
print(driver.title)
finally:
driver.quit()
Because ChromeDriver did not launch that browser, its startup automation extension was not loaded into the existing session. Some commands can therefore be unavailable.
Remote WebDriver and Selenium Grid
For Grid or another remote service, pass the service’s documented URL to the remote driver and pass Chrome options separately. The URL might look like https://grid.example.test/wd/hub; it is not a debuggerAddress.
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--headless=new")
driver = webdriver.Remote(
command_executor="https://grid.example.test/wd/hub",
options=options,
)
try:
driver.get("https://example.com")
print(driver.title)
finally:
driver.quit()
Why the remote-debugging error appears
ChromeDriver documents that commands such as browser-window resizing rely on an automation extension loaded when ChromeDriver starts a new session. An attached browser did not receive that startup extension, so those commands can fail with an error such as operation not supported when using remote debugging. The documented remedy is to rewrite the test to launch a new Chrome session by removing debuggerAddress. Read the ChromeDriver troubleshooting page.
Configuration checklist
- Decide whether ChromeDriver should launch Chrome or reuse an existing process.
- For a new local session, instantiate
ChromeOptionsand pass it toChromeDriver. - Remove every
debuggerAddresscapability from the new-session path. - For Grid, supply the Grid command endpoint to
Remoteand options separately. - Call
quit()(or the equivalent) in a cleanup block. - Use a compatible Chrome, ChromeDriver, and Selenium installation.
Troubleshooting
“Operation not supported when using remote debugging”
Cause: the session is attached to an existing Chrome. Fix: remove debuggerAddress and start a new session. If attachment is mandatory, avoid commands that require the startup automation extension.
Chrome starts, then the driver exits
Cause: a browser/driver mismatch, an invalid Chrome binary path, or an environment that cannot start a display. Fix: verify the installed versions and binary path, and use a supported headless argument in a display-less environment.
Connection refused at port 9222
Cause: no Chrome debugging server is listening there, or it is bound to another host or port. Fix: use a fresh local session, or start the existing Chrome with remote debugging and use its actual address.
Grid returns a session-creation error
Cause: the Grid URL is wrong or the requested browser capabilities cannot be fulfilled. Fix: check the provider’s exact endpoint and send a normal Chrome options object. Do not put the Grid URL in debuggerAddress.
Window sizing behaves differently
Cause: an attached session may not have ChromeDriver’s automation extension. Fix: launch a fresh session, then set the window size through the normal WebDriver API.
The script hangs during cleanup
Cause: the browser process is already owned by another tool or has become unresponsive. Fix: ensure one owner per browser session and always clean up in a finally block.
Performance, reliability and cost considerations
- The official documentation does not establish a general speed or reliability advantage for either launch mode. Choose based on ownership and command support.
- A fresh session is usually simpler to reproduce because ChromeDriver controls browser startup, options and cleanup in one process.
- Attachment can be useful for preserving an already authenticated browser, but it adds an external dependency: the target Chrome must remain alive and reachable at the debugger address.
- Grid execution adds a network hop. Keep the endpoint close to the test runner when latency matters and configure session timeouts according to the Grid provider’s documentation.
- Selenium itself has no per-screenshot cost. Browser hosting, Grid usage and CI runtime are billed by whichever infrastructure you choose.
Or skip the browser setup
If your goal is a clean image or PDF rather than interactive browser control, ScreenshotNeo provides a single HTTP request. Its API accepts the URL and returns PNG, JPEG, WebP or PDF. The request below does not require ChromeDriver, a debugger port or a Grid.
See the ScreenshotNeo API documentation for all options.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Cookie banners, newsletter popups and chat widgets are removed before the shot. Bot checks, blank pages and failed loads are never billed, and response headers identify the page verdict and billing status. An MCP server lets AI agents take screenshots with tools such as take_screenshot, get_page_info and capture_pdf. One thousand screenshots a month are free with no card; paid plans start at $5 for 3,000.
Create a free ScreenshotNeo account.
FAQ
Do I need a debugger address for Selenium?
No. You need it only to attach ChromeDriver to an existing Chrome debugging server.
Is a debugger address the same as a Selenium Grid URL?
No. The debugger address identifies Chrome’s DevTools server. The Grid URL identifies the remote WebDriver service.
Can I keep cookies without attaching to Chrome?
Yes. Use a dedicated profile or restore cookies through WebDriver APIs in a newly launched session, subject to your test’s security requirements.
Why does attaching sometimes work for navigation but fail for resizing?
Navigation may work while commands that depend on ChromeDriver’s startup automation extension remain unsupported.


