{"record":{"id":"6101d5c2feb7e772","repo":"SeleniumHQ/selenium","slug":"can-t-find-free-port-e","errorCode":null,"errorMessage":"Can't find free port: ({e})","messagePattern":"Can't find free port: \\((.+?)\\)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"py/selenium/webdriver/common/utils.py","lineNumber":54,"sourceCode":"    try:\n        # IPv4\n        free_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n        free_socket.bind((\"127.0.0.1\", 0))\n    except OSError:\n        if free_socket:\n            free_socket.close()\n        # IPv6\n        try:\n            free_socket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)\n            free_socket.bind((\"::1\", 0))\n        except OSError:\n            if free_socket:\n                free_socket.close()\n            raise RuntimeError(\"Can't find free port (Unable to bind to IPv4 or IPv6)\")\n    try:\n        port: int = free_socket.getsockname()[1]\n    except Exception as e:\n        raise RuntimeError(f\"Can't find free port: ({e})\")\n    finally:\n        free_socket.close()\n    return port\n\n\ndef find_connectable_ip(host: str | bytes | None, port: int | None = None) -> str | None:\n    \"\"\"Resolve a hostname to an IP, preferring IPv4 addresses.\n\n    We prefer IPv4 so that we don't change behavior from previous IPv4-only\n    implementations, and because some drivers (e.g., FirefoxDriver) do not\n    support IPv6 connections.\n\n    If the optional port number is provided, only IPs that listen on the given\n    port are considered.\n\n    Args:\n        host: hostname\n        port: port number","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/py/selenium/webdriver/common/utils.py#L36-L72","documentation":"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.","triggerScenarios":"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.","commonSituations":"Concurrent code racing to close the socket, a buggy socket mock in tests, or a platform-specific socket quirk. Practically unseen in production.","solutions":["Read the interpolated exception in the message to identify the underlying cause.","Pass an explicit port to the Service to bypass free_port() entirely.","Ensure no concurrent access to the Service port- allocation path.","If this occurs under a test double, fix the mock to support getsockname."],"exampleFix":"# defensive — supply a fixed port to avoid the free_port path\nservice = Service(executable_path='/path/driver', port=9515)","handlingStrategy":"fallback","validationCode":"null","typeGuard":"null","tryCatchPattern":"try:\n    service = Service(executable_path=drv)\nexcept RuntimeError as e:\n    if \"Can't find free port\" in str(e):\n        service = Service(executable_path=drv, port=9515)","preventionTips":["Pass an explicit port to avoid the free_port path entirely.","Avoid concurrent construction of many Services that all call free_port().","Do not mock socket.socket at a granularity that breaks getsockname."],"tags":["network","port","race-condition","defensive"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}