ScreenshotNeo

BlogHow-to

Making WebDriver Requests Without Specifying a Debugger Address

Start a fresh ChromeDriver session without debuggerAddress, understand remote debugging limits, and fix unsupported-operation errors.

By the ScreenshotNeo team1 October 20266 min read

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

  1. Decide whether ChromeDriver should launch Chrome or reuse an existing process.
  2. For a new local session, instantiate ChromeOptions and pass it to ChromeDriver.
  3. Remove every debuggerAddress capability from the new-session path.
  4. For Grid, supply the Grid command endpoint to Remote and options separately.
  5. Call quit() (or the equivalent) in a cleanup block.
  6. 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.