{"record":{"id":"44adccb0efef19c7","repo":"apache/pulsar","slug":"failed-to-bind-extension-extensionname-on-a","errorCode":null,"errorMessage":"Failed to bind extension `${extensionName}` on ${address}","messagePattern":"Failed to bind extension `(.+?)` on (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyService.java","lineNumber":457,"sourceCode":"            bootstrap.childOption(ChannelOption.TCP_NODELAY, true);\n            bootstrap.childOption(ChannelOption.RCVBUF_ALLOCATOR,\n                    new AdaptiveRecvByteBufAllocator(1024, 16 * 1024, 1 * 1024 * 1024));\n\n            EventLoopUtil.enableTriggeredMode(bootstrap);\n            DefaultThreadFactory defaultThreadFactory = new DefaultThreadFactory(\"pulsar-ext-\" + extensionName);\n            EventLoopGroup dedicatedWorkerGroup =\n                    EventLoopUtil.newEventLoopGroup(proxyConfig.getNumIOThreads(), false, defaultThreadFactory);\n            extensionsWorkerGroups.add(dedicatedWorkerGroup);\n            bootstrap.channel(EventLoopUtil.getServerSocketChannelClass(dedicatedWorkerGroup));\n            bootstrap.group(this.acceptorGroup, dedicatedWorkerGroup);\n        } else {\n            bootstrap = serverBootstrap.clone();\n        }\n        bootstrap.childHandler(initializer);\n        try {\n            bootstrap.bind(address).sync();\n        } catch (Exception e) {\n            throw new IOException(\"Failed to bind extension `\" + extensionName + \"` on \" + address, e);\n        }\n        log.info()\n                .attr(\"extensionName\", extensionName)\n                .attr(\"address\", address)\n                .log(\"Successfully bound extension\");\n    }\n\n    public BrokerDiscoveryProvider getDiscoveryProvider() {\n        return discoveryProvider;\n    }\n\n    public void close() throws IOException {\n        if (listenChannel != null) {\n            try {\n                listenChannel.close().sync();\n            } catch (InterruptedException e) {\n                log.info(\"Shutdown of listenChannel interrupted\");\n                Thread.currentThread().interrupt();","sourceCodeStart":439,"sourceCodeEnd":475,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyService.java#L439-L475","documentation":"ProxyService.startProxyExtension binds a Netty bootstrap for each configured proxy extension at its advertised address. If bind fails, the IOException names the extension and address so the operator knows which add-on listener is broken. Fail-fast behavior ensures extensions are not silently unavailable while the core proxy runs.","triggerScenarios":"Calling ProxyService.start (which calls startProxyExtensions -> startProxyExtension) when an extension's configured bind address/port is already occupied, is a privileged port without permission, or the address does not exist on the host; the underlying bootstrap.bind(address).sync() throws and is wrapped in IOException.","commonSituations":"Two extensions configured with the same bind port; extension port colliding with a core proxy or broker port; leftover process from a previous test run holding the port; configuring a hostname that doesn't resolve to a local interface in a container.","solutions":["Check the extension's configured bind address/port and free the conflicting port (kill the stale process or pick a new port)","Ensure no two proxy extensions or core proxy ports overlap in configuration","Verify the bind address is a valid local interface and adjust if running in a container/VM","Re-run the proxy after correcting the extension port config"],"exampleFix":"// before\nproxyExtensions=org.apache.pulsar.proxy.extension.socks5.Socks5ProxyService\nproxyExtensionPort0=1080  # occupied by a running SOCKS proxy\n\n// after\nproxyExtensionPort0=1081","handlingStrategy":"validation","validationCode":"InetSocketAddress addr = resolveExtensionAddress(extensionName);\ntry (ServerSocket ss = new ServerSocket()) {\n    ss.bind(addr);\n} catch (IOException e) {\n    throw new IllegalStateException(\"Extension \" + extensionName + \" port \" + addr.getPort()\n        + \" unavailable: \" + e.getMessage());\n}","typeGuard":"boolean extensionPortUnique(ProxyConfiguration cfg, int port) {\n    return port != cfg.getServicePort().orElse(-1)\n        && port != cfg.getServicePortTls().orElse(-1)\n        && port != cfg.getWebServicePort().orElse(-1);\n}","tryCatchPattern":"try {\n    proxyService.start();\n} catch (IOException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Failed to bind extension\")) {\n        LOG.error(\"Proxy extension bind failed: {} (cause: {})\", e.getMessage(), e.getCause());\n    }\n    throw e;\n}","preventionTips":["Assign each proxy extension a distinct, non-overlapping port","Check extension ports against core proxy/broker ports when planning deployments","Kill stale processes from previous runs before starting extensions","Verify the configured bind address exists on the host (especially in containers)"],"tags":["pulsar-proxy","network","bind-exception","extensions","port-in-use"],"backgroundTag":"address-already-in-use","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"}