SeleniumHQ/selenium · critical · RuntimeError

Can't find free port (Unable to bind to IPv4 or IPv6)

Error message

Can't find free port (Unable to bind to IPv4 or IPv6)

What it means

Raised by utils.free_port() when binding a TCP socket to 127.0.0.1:0 (IPv4) fails with OSError AND the IPv6 fallback bind to [::1]:0 also fails. free_port is called by Service.__init__ (default port=0) to let the OS assign an ephemeral port. Failing both families means the host cannot allocate any loopback listener socket at all.

Source

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

    First try IPv4, but use IPv6 if it can't bind (IPv6-only system).
    """
    free_socket = None
    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.

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Pass an explicit port to the Service to avoid the free_port() call: Service(port=9515).
  2. Loosen the container/jail networking so loopback binds are permitted.
  3. If running under a custom socket-mocking test layer, ensure socket.socket().bind is not unconditionally raising.
  4. Check for ephemeral port exhaustion: raise net.ipv4.ip_local_port_range or reduce TIME_WAIT sockets.

Example fix

# before — free_port() fails in a locked container
service = Service(executable_path='/path/driver')  # port defaults to 0 -> free_port()

# after — supply a fixed port
service = Service(executable_path='/path/driver', port=9515)
Defensive patterns

Strategy: fallback

Validate before calling

null

Type guard

null

Try / catch

import socket
try:
    s = socket.socket(); s.bind(('127.0.0.1', 0)); s.close()
except OSError:
    port = 9515  # fixed fallback
else:
    port = 0  # let Service pick

Prevention

When it happens

Trigger: A sandbox/container with loopback networking disabled, an environment where both IPv4 and IPv6 loopback binds are denied by seccomp/AppArmor, or extreme ephemeral-port exhaustion. Extremely rare on normal hosts.

Common situations: Overly restrictive container security profiles (no network namespace loopback), locked-down CI runners, or test harnesses that mock out the socket module incorrectly. Also seen in some minimal BSD jails.

Related errors


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