skip to content

In Selenium, which port does ChromeDriverService listen on if you never call usingPort, and how do you pin it?

level: middleimportance: should knowfreq 52%

answer

  1. The service decides the address
  2. You rarely get 9515 by accident
  3. Builder probes before the process starts
  4. One method pins, one asks for any
  5. usingPort versus usingAnyFreePort

basics

~10 s

Selenium's driver-service builder picks a port that is free at build time, so every service gets a different one. Call usingPort(9515) to pin a fixed port, or usingAnyFreePort() to state the default choice explicitly.

solid answer

~40 s

In Selenium 4's Java bindings, `ChromeDriverService.Builder.build()` settles on a free ephemeral port unless you asked for a specific one, so two services started in the same JVM never collide. `usingPort(9515)` pins the port and `usingAnyFreePort()` states the default explicitly. Whatever number is chosen is handed to the executable as `--port=<n>` on its command line, which is why chromedriver's own shell default of 9515 and geckodriver's of 4444 rarely apply when Selenium is the launcher. Once `start()` returns, `service.getUrl()` gives the `http://localhost:<port>` the driver is answering on. Pin a port only when something outside the JVM has to reach that driver; otherwise a free port removes a whole class of address-already-in-use failures caused by a previous run leaving a driver behind.

code

java · 13 lines
java
ChromeDriverService service = new ChromeDriverService.Builder()
    .usingPort(9515)
    .build();
service.start();
System.out.println(service.getUrl());

WebDriver driver = new ChromeDriver(service, new ChromeOptions());
driver.get("https://lims.internal.example/samples");
int rows = driver.findElements(By.cssSelector("table#sample-log tbody tr")).size();
System.out.println("sample rows: " + rows);

driver.quit();
service.stop();

go deeper

for a junior

Be ready to say that the driver is a separate program listening on a port and that the client talks to it over HTTP. Knowing that 9515 is chromedriver's own default is enough at this level.

for a middle

Explain that the builder settles on a free port unless usingPort was called, that the number reaches the executable as a --port argument, and what changes when you pin one.

for a senior

Show the operational side: a pinned port turns a leaked driver into a loud bind failure, while a free port hides the same leak. Say when you would accept each.

for a principal

Own the convention across suites: which runs may pin a port on shared build agents, how addresses are discovered rather than assumed, and how port policy interacts with cleaning up leftover processes.

## What the port is actually addressing Selenium's Java client never touches Chrome directly. **ChromeDriver** is a standalone executable that runs a small HTTP server, and the client sends **W3C WebDriver** commands to it as ordinary HTTP requests — `POST /session` to open a session, then further requests to locate the accession-number column of a laboratory sample-tracking table and read its cells. `ChromeDriverService` is the Java object that owns that executable: it assembles the command line, spawns the process, waits for it to come up, and knows the address it answers on. Everything about that address is fixed except the **port**, which is why port selection is the one decision the service pushes onto you. ## How Selenium 4 chooses the port - `ChromeDriverService.Builder`, `GeckoDriverService.Builder` and `EdgeDriverService.Builder` all extend the same `DriverService.Builder`, so the port rules are identical for the three of them. - If you never call `usingPort(int)`, the builder finds a port that is free at build time — exactly what `usingAnyFreePort()` asks for explicitly. The probe lives in `org.openqa.selenium.net.PortProber`. - The number chosen is passed to the executable on its command line as `--port=<n>`. That is why chromedriver's own default of **9515** and geckodriver's of **4444** rarely apply under Selenium: those defaults only take effect when you launch the binary yourself from a shell with no flag. - The port belongs to the **service**, not to a session. One driver process on one port can host more than one session at a time. - A free port is probed, not reserved: the builder finds a number nobody holds, releases its own socket, and hands the number to the process a moment later. The window is tiny but not zero, so an in-use failure on a busy host is not impossible even here. What actually happens when you write `new ChromeDriver()` and let Selenium build the service for you: 1. The builder locates the executable and settles on a port. 2. `start()` spawns the process with `--port=<n>` on its command line. 3. `start()` blocks, polling the driver until it answers, so no command is ever sent to a socket nobody is listening on yet. 4. The new-session request goes to `http://localhost:<n>/session`. 5. `getUrl()` reports that base address for as long as the service is running. ## Free port versus pinned port | | Free port (the default) | `usingPort(9515)` | |---|---|---| | Chosen | at build time, by probing | by you, when you write the code | | Two suites on one host | both start | the second one fails to bind | | A leftover driver on that port | irrelevant, another number is used | `start()` fails | | Known before the service starts | no — read `getUrl()` after | yes | | Fits | ordinary local and CI runs | a driver something outside the JVM must reach | ## When pinning earns its keep Pin the port when an actor outside the JVM that built the service needs the address in advance. Three real cases: 1. A `RemoteWebDriver` created in a different process has to be given a URL, and it cannot ask your builder what it picked. 2. A pipeline step that checks the sample-tracking suite's driver is alive wants a stable address to probe, such as `http://localhost:9515/status`. 3. An engineer diagnosing a stuck run wants one known address rather than a guess among several running drivers. Pinning also makes a leak **visible**. A fixed port that is already busy at the start of the next nightly run is a loud signal that the previous run left a driver process behind; a free port quietly routes around exactly the same leak and lets it accumulate for weeks. ## The failure a pinned port produces If a driver process from a killed run still holds 9515, a new service built with `usingPort(9515)` cannot bind. The executable exits immediately and `start()` fails, which is the good outcome: the alternative — a client silently talking to a stale driver process from yesterday's run — produces a sample-tracking suite that opens browsers nobody is watching and fails with errors that make no sense against the current code. Read the bind failure as a diagnosis rather than a nuisance, and clean up the host instead of moving to a different fixed number. ## Reading the port back `service.getUrl()` returns a `java.net.URL` of the form `http://localhost:<port>` once the service is running, and `service.isRunning()` reports whether the process is alive. Logging that URL at the start of a run costs nothing and turns "which of these four chromedriver processes was mine?" into a lookup rather than an investigation.

  • Two suites run on the same build agent and both pin port 9515. What do you see?
    Whichever starts second cannot bind, so its executable exits and `start()` fails before any session is opened. The fix is to stop pinning in at least one of them: a free ephemeral port makes the two runs independent, and each can still discover its own address through `service.getUrl()` if it needs to log or probe it.
  • Does pinning the port limit you to one browser session on that driver?
    No. The port identifies the driver process, not a session. A single chromedriver on 9515 can hold several sessions at once, each with its own session id, and the client addresses them through the id in the request path rather than through separate ports.
  • How would you discover the port when Selenium chose it for you?
    Call `service.getUrl()` after `start()` and log it. If Selenium built the service implicitly inside `new ChromeDriver()` you do not hold that object, so the practical answer is to build the service yourself when you need the address — that is one of the main reasons to build it explicitly at all.

saying these in an interview costs you the question

  • Believing Selenium always uses port 9515 for ChromeDriver
  • Assuming the port identifies a session rather than the process
  • Pinning a fixed port in every suite by habit
  • Thinking a free port is reserved rather than probed
  • Treating a bind failure as a reason to pick another number