apache/pulsar · error · IllegalArgumentException

must not specify `${hostPort}` to different listener.

Error message

must not specify `${hostPort}` to different listener.

What it means

The validator builds a reverse mapping from each URI's host:port to the listener names using it. If the same host:port is assigned to more than one listener name, client routing by address becomes ambiguous, so parseAdvertisedListeners throws this IllegalArgumentException (it is then wrapped by the catch block as "the value ... is invalid").

Source

Thrown at pulsar-broker-common/src/main/java/org/apache/pulsar/broker/validator/MultipleListenerValidator.java:230

                            pulsarHttpAddress = uri;
                        } else {
                            throw new IllegalArgumentException("there are redundant configure for listener `"
                                    + entry.getKey() + "`");
                        }
                    } else if ("https".equalsIgnoreCase(uri.getScheme())) {
                        if (pulsarHttpsAddress == null) {
                            pulsarHttpsAddress = uri;
                        } else {
                            throw new IllegalArgumentException("there are redundant configure for listener `"
                                    + entry.getKey() + "`");
                        }
                    }

                    String hostPort = formatHostPort(uri);
                    Set<String> sets = reverseMappings.computeIfAbsent(hostPort, k -> new TreeSet<>());
                    sets.add(entry.getKey());
                    if (sets.size() > 1) {
                        throw new IllegalArgumentException("must not specify `" + hostPort
                                + "` to different listener.");
                    }
                } catch (Throwable cause) {
                    throw new IllegalArgumentException("the value " + strUri + " in the `advertisedListeners` "
                            + "configure is invalid", cause);
                }
            }
            result.put(entry.getKey(), AdvertisedListener.builder()
                    .brokerServiceUrl(pulsarAddress)
                    .brokerServiceUrlTls(pulsarSslAddress)
                    .brokerHttpUrl(pulsarHttpAddress)
                    .brokerHttpsUrl(pulsarHttpsAddress)
                    .build());
        }
        return result;
    }

    /**

View on GitHub (pinned to 820761864e)

Solutions

  1. Give each listener a unique host:port — change the port of one of the conflicting URIs
  2. If both listeners must expose the same address, collapse them into a single listener name
  3. Check behind any proxies/LB: the advertised host:port itself must differ per listener

Example fix

// before
advertisedListeners=internal:pulsar://h1:6650,external:pulsar://h1:6650
// after
advertisedListeners=internal:pulsar://h1:6650,external:pulsar://h1:16650
Defensive patterns

Strategy: validation

Validate before calling

Set<String> seen = new HashSet<>();
for (String entry : advertisedListeners.split(",")) {
    URI uri = URI.create(entry.substring(entry.indexOf(':') + 1).trim());
    String hostPort = uri.getHost() + ":" + uri.getPort();
    if (!seen.add(hostPort))
        throw new IllegalStateException("host:port " + hostPort + " used by multiple listeners");
}

Try / catch

try {
    startBroker(config);
} catch (IllegalArgumentException e) {
    log.error("Listener port conflict: {}", e.getMessage());
    throw e;
}

Prevention

When it happens

Trigger: Two different listener names in `advertisedListeners` whose URIs resolve to the identical host:port, e.g. `a:pulsar://h:6650` and `b:pulsar://h:6650` (host:port comparison after formatHostPort, case-insensitive scheme handling).

Common situations: Cloning a listener block and only renaming the listener, not the port; advertising the same port for internal and external listeners; one entry pointing at a shared LB address used by another listener.

Related errors


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