{"record":{"id":"5d92806fd2db25b6","repo":"apache/pulsar","slug":"unable-to-allocate-socket-port","errorCode":null,"errorMessage":"Unable to allocate socket port","messagePattern":"Unable to allocate socket port","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-common/src/main/java/org/apache/pulsar/common/util/PortManager.java","lineNumber":50,"sourceCode":"    private static final Set<Integer> PORTS = new HashSet<>();\n\n    /**\n     * Return a free port that is reserved for the caller until {@link #releaseLockedPort(int)}\n     * is invoked.\n     */\n    public static synchronized int nextLockedFreePort() {\n        int exceptionCount = 0;\n        while (true) {\n            try (ServerSocket ss = new ServerSocket(0)) {\n                int port = ss.getLocalPort();\n                if (!checkPortIfLocked(port)) {\n                    PORTS.add(port);\n                    return port;\n                }\n            } catch (Exception e) {\n                exceptionCount++;\n                if (exceptionCount > 100) {\n                    throw new RuntimeException(\"Unable to allocate socket port\", e);\n                }\n            }\n        }\n    }\n\n    /**\n     * Release a previously locked port.\n     *\n     * @return true if the port was previously locked by this manager\n     */\n    public static synchronized boolean releaseLockedPort(int lockedPort) {\n        return PORTS.remove(lockedPort);\n    }\n\n    /**\n     * @return true if the port is currently locked by this manager\n     */\n    public static synchronized boolean checkPortIfLocked(int lockedPort) {","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-common/src/main/java/org/apache/pulsar/common/util/PortManager.java#L32-L68","documentation":"PortManager is a test/admin utility that hands out free TCP ports by probing sockets. It tries up to 100 times to bind a candidate port; if every attempt throws (e.g. bind failures), it aborts with this RuntimeException wrapping the last cause. It means the JVM could not find or allocate any usable socket port after repeated attempts.","triggerScenarios":"Calling nextLockedFreePort() in a tight loop so that more than 100 consecutive attempts to open a candidate port throw; port exhaustion by other processes; restrictive firewall/OS bind restrictions.","commonSituations":"Test suites that run many brokers/clients concurrently and exhaust the ephemeral port range; running in a container with a narrow net.ipv4.ip_local_port_range; leaked sockets from previous tests holding ports in TIME_WAIT.","solutions":["Investigate the wrapped cause `e` printed with this exception — fix the underlying bind/IO error","Check for port exhaustion: netstat/ss for TIME_WAIT or listening sockets and raise net.ipv4.ip_local_port_range","Reduce concurrency or reuse allocated ports instead of allocating a new port per object","Restart the host or container to clear leaked/ephemeral ports"],"exampleFix":"// before: allocating a fresh port per test method\nint port = PortManager.nextLockedFreePort(); // throws after 100 failures\n// after: reuse the locked port across the suite\nprivate static final AutoCloseable LOCK = PortManager.acquireLock();\nint port = PortManager.nextLockedFreePort();","handlingStrategy":"retry","validationCode":"// check port availability before relying on PortManager\ntry (java.net.ServerSocket s = new java.net.ServerSocket()) {\n    s.bind(new java.net.InetSocketAddress(0));\n} catch (java.io.IOException e) {\n    throw new IllegalStateException(\"No bindable ports available: \" + e.getMessage());\n}","typeGuard":null,"tryCatchPattern":"try {\n    int port = PortManager.nextLockedFreePort();\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"Unable to allocate socket port\")) {\n        // fall back to ephemeral port (0) or abort with diagnostics\n    }\n}","preventionTips":["Bind to port 0 (ephemeral) when a fixed allocated port is not required","Monitor TIME_WAIT/socket counts in CI hosts running parallel test suites","Raise net.ipv4.ip_local_port_range on test machines/containers","Reuse one locked port per test class instead of per test method"],"tags":["network","sockets","port-exhaustion","testing"],"backgroundTag":"port-allocation-failed","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}