apache/pulsar · critical · RuntimeException

Protocol handler for `${handler}` attempts to use ${address}

Error message

Protocol handler for `${handler}` attempts to use ${address} for its listening port. But it is already occupied by other messaging protocols

What it means

Thrown by ProtocolHandlers.newChannelInitializers when two messaging protocol handlers try to bind the same listening address. Each address may be owned by exactly one protocol; a duplicate would create ambiguous channel initialization.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/protocol/ProtocolHandlers.java:145

                e -> e.getValue().getProtocolDataToAdvertise()
            ));
    }

    public Map<String, Map<InetSocketAddress, ChannelInitializer<SocketChannel>>> newChannelInitializers() {
        Map<String, Map<InetSocketAddress, ChannelInitializer<SocketChannel>>> channelInitializers = new HashMap<>();
        Set<InetSocketAddress> addresses = new HashSet<>();

        for (Map.Entry<String, ProtocolHandlerWithClassLoader> handler : handlers.entrySet()) {
            Map<InetSocketAddress, ChannelInitializer<SocketChannel>> initializers =
                handler.getValue().newChannelInitializers();
            initializers.forEach((address, initializer) -> {
                if (!addresses.add(address)) {
                    log.error()
                            .attr("handler", handler.getKey())
                            .attr("address", address)
                            .log("Protocol handler attempts to use listening port already occupied by other"
                                    + " messaging protocols");
                    throw new RuntimeException("Protocol handler for `" + handler.getKey()
                        + "` attempts to use " + address + " for its listening port. But it is"
                        + " already occupied by other messaging protocols");
                }
                channelInitializers.put(handler.getKey(), initializers);
                endpoints.put(address, handler.getKey());
            });
        }

        return channelInitializers;
    }

    public void start(BrokerService service) {
        handlers.values().forEach(handler -> handler.start(service));
    }

    @Override
    public void close() {
        handlers.values().forEach(ProtocolHandler::close);

View on GitHub (pinned to 820761864e)

Solutions

  1. Give each protocol handler a unique listen address/port in its configuration.
  2. If one handler should serve multiple protocol names, register it once and let it expose multiple endpoints internally instead of loading it twice.
  3. Review the broker.conf / handler-specific conf for duplicated bindAddress values and remove the duplicate.
  4. Restart after fixing; the log names both the conflicting handler and address.

Example fix

// before
kafkaBindAddress=0.0.0.0:6650
kopaBindAddress=0.0.0.0:6650
// after
kafkaBindAddress=0.0.0.0:6650
kopaBindAddress=0.0.0.0:6651
Defensive patterns

Strategy: validation

Validate before calling

// Pre-startup check: all handler bind addresses must be unique
java.util.Set<String> seen = new java.util.HashSet<>();
for (String addr : allHandlerBindAddresses) { // gathered from each handler's conf
  if (!seen.add(addr))
    throw new IllegalStateException("Duplicate bind address across protocol handlers: " + addr);
}

Try / catch

try {
  handlers = ProtocolHandlers.load(conf);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().contains("already occupied by other messaging protocols")) {
    log.error("Two handlers claim the same listen address; assign unique ports");
  }
  throw e;
}

Prevention

When it happens

Trigger: During broker service startup, multiple configured handlers return the same bind address from getProtocolDataToAdvertise/endpoint setup, so addresses.add(address) returns false.

Common situations: Two protocol NARs (e.g. kafka-on-pulsar with two listeners) configured with identical host:port; duplicated bindAddress entries in handler configuration; copy-pasted listener config between protocols.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/d9f23c02e8aa00e5. Report an issue: GitHub.