SeleniumHQ/selenium · error · RuntimeError

Can't find free port: ({e})

Error message

Can't find free port: ({e})

What it means

Raised by utils.free_port() if calling getsockname() on the successfully-bound socket raises an unexpected exception. This is a defensive catch around the otherwise-straightforward port extraction after a successful bind; it should essentially never fire under normal conditions.

Source

Thrown at py/selenium/webdriver/common/utils.py:54

    try:
        # IPv4
        free_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        free_socket.bind(("127.0.0.1", 0))
    except OSError:
        if free_socket:
            free_socket.close()
        # IPv6
        try:
            free_socket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
            free_socket.bind(("::1", 0))
        except OSError:
            if free_socket:
                free_socket.close()
            raise RuntimeError("Can't find free port (Unable to bind to IPv4 or IPv6)")
    try:
        port: int = free_socket.getsockname()[1]
    except Exception as e:
        raise RuntimeError(f"Can't find free port: ({e})")
    finally:
        free_socket.close()
    return port


def find_connectable_ip(host: str | bytes | None, port: int | None = None) -> str | None:
    """Resolve a hostname to an IP, preferring IPv4 addresses.

    We prefer IPv4 so that we don't change behavior from previous IPv4-only
    implementations, and because some drivers (e.g., FirefoxDriver) do not
    support IPv6 connections.

    If the optional port number is provided, only IPs that listen on the given
    port are considered.

    Args:
        host: hostname
        port: port number

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Read the interpolated exception in the message to identify the underlying cause.
  2. Pass an explicit port to the Service to bypass free_port() entirely.
  3. Ensure no concurrent access to the Service port- allocation path.
  4. If this occurs under a test double, fix the mock to support getsockname.

Example fix

# defensive — supply a fixed port to avoid the free_port path
service = Service(executable_path='/path/driver', port=9515)
Defensive patterns

Strategy: fallback

Validate before calling

null

Type guard

null

Try / catch

try:
    service = Service(executable_path=drv)
except RuntimeError as e:
    if "Can't find free port" in str(e):
        service = Service(executable_path=drv, port=9515)

Prevention

When it happens

Trigger: The socket bound successfully but getsockname() then raised — possible if the socket was closed by another thread between bind and getsockname, or under exotic socket-implementation bugs / aggressive GC of the socket object. The specific exception is interpolated into the message.

Common situations: Concurrent code racing to close the socket, a buggy socket mock in tests, or a platform-specific socket quirk. Practically unseen in production.

Related errors


AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14). Data as JSON: /api/errors/6101d5c2feb7e772. Report an issue: GitHub.