{"record":{"id":"dd17cae8ebd05fdd","repo":"apache/pulsar","slug":"no-free-port-found","errorCode":null,"errorMessage":"No free port found","messagePattern":"No free port found","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionCommon.java","lineNumber":83,"sourceCode":"\n/**\n * Utils used for runtime.\n */\n@CustomLog\n@NoArgsConstructor(access = AccessLevel.PRIVATE)\npublic class FunctionCommon {\n\n    public static int findAvailablePort() {\n        // The logic here is a little flaky. There is no guarantee that this\n        // port returned will be available later on when the instance starts\n        // TODO:- Fix this.\n        try {\n            ServerSocket socket = new ServerSocket(0);\n            int port = socket.getLocalPort();\n            socket.close();\n            return port;\n        } catch (IOException ex) {\n            throw new RuntimeException(\"No free port found\", ex);\n        }\n    }\n\n    public static TypeDefinition[] getFunctionTypes(FunctionConfig functionConfig, TypePool typePool)\n            throws ClassNotFoundException {\n        return getFunctionTypes(functionConfig, typePool.describe(functionConfig.getClassName()).resolve());\n    }\n\n    public static TypeDefinition[] getFunctionTypes(FunctionConfig functionConfig, TypeDefinition functionClass) {\n        boolean isWindowConfigPresent = functionConfig.getWindowConfig() != null;\n        return getFunctionTypes(functionClass, isWindowConfigPresent);\n    }\n\n    public static TypeDefinition[] getFunctionTypes(TypeDefinition userClass, boolean isWindowConfigPresent) {\n        Class<?> classParent = getFunctionClassParent(userClass, isWindowConfigPresent);\n        TypeList.Generic typeArgsList = resolveInterfaceTypeArguments(userClass, classParent);\n        TypeDescription.Generic[] typeArgs = new TypeDescription.Generic[2];\n        typeArgs[0] = typeArgsList.get(0);","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionCommon.java#L65-L101","documentation":"FunctionCommon.findAvailablePort asks the OS for an ephemeral port by opening a ServerSocket on port 0 and returning its local port. If binding a server socket fails with an IOException (e.g. the OS has exhausted ephemeral ports or sockets cannot be created), this RuntimeException wrapping the IOException is thrown. It means no free port could be obtained, not that a specific port was taken.","triggerScenarios":"Calling findAvailablePort() when new ServerSocket(0) throws IOException — typically ephemeral port exhaustion (net.ipv4.ip_local_port_range full, TIME_WAIT buildup), file-descriptor/ulimit limits, or a restrictive security policy blocking socket creation.","commonSituations":"Hosts running many functions/instances simultaneously with heavy churn of short-lived connections; containers with low ulimit -n; misconfigured TCP stacks after load tests; IPv4/IPv6 stack issues in restricted environments.","solutions":["Check and increase the ephemeral port range (Linux: net.ipv4.ip_local_port_range) and enable net.ipv4.tcp_tw_reuse","Raise the file-descriptor limit (ulimit -n / nofile) for the process running the functions worker","Reduce connection churn or restart services holding thousands of TIME_WAIT sockets","Inspect the wrapped IOException cause to confirm whether it is EMFILE/ENFILE vs address-family issues"],"exampleFix":"// host tuning\n// before\nnet.ipv4.ip_local_port_range = 1024 32767\n// after\nnet.ipv4.ip_local_port_range = 1024 65535\nsysctl -w net.ipv4.tcp_tw_reuse=1","handlingStrategy":"retry","validationCode":"// No reliable pre-check exists; probe system health beforehand\nlong open = java.lang.management.ManagementFactory\n    .getPlatformMBeanServer()\n    .getAttribute(javax.management.ObjectName.getInstance(\"java.lang:type=OperatingSystem\"), \"OpenFileDescriptorCount\") != null\n    ? (Long) java.lang.management.ManagementFactory.getPlatformMBeanServer()\n        .getAttribute(javax.management.ObjectName.getInstance(\"java.lang:type=OperatingSystem\"), \"OpenFileDescriptorCount\") : 0;\nlong max = (Long) java.lang.management.ManagementFactory.getPlatformMBeanServer()\n    .getAttribute(javax.management.ObjectName.getInstance(\"java.lang:type=OperatingSystem\"), \"MaxFileDescriptorCount\");\nif (open > max * 0.9) log.warn(\"File descriptors nearly exhausted (\" + open + \"/\" + max + \"), port allocation may fail\");","typeGuard":null,"tryCatchPattern":"int port;\ntry {\n    port = FunctionCommon.findAvailablePort();\n} catch (RuntimeException e) {\n    if (e.getCause() instanceof IOException) {\n        log.warn(\"Port probe failed, retrying after backoff\", e);\n        Thread.sleep(500);\n        port = FunctionCommon.findAvailablePort(); // retry once or use fallback range\n    } else throw e;\n}","preventionTips":["Raise ulimit -n for the functions worker process","Widen the OS ephemeral port range and enable tcp_tw_reuse on busy hosts","Avoid opening thousands of short-lived client connections from the same host","Monitor fd/TIME_WAIT counts and alert before exhaustion"],"tags":["network","port-allocation","resource-exhaustion"],"backgroundTag":"no-free-port-available","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"}