apache/pulsar · error · IllegalArgumentException
webServicePort/webServicePortTls or http/https bindAddresses
Error message
webServicePort/webServicePortTls or http/https bindAddresses must be present
What it means
During PulsarService.start(), the broker validates that an HTTP(S) web service endpoint can be bound. It requires at least one of: a non-empty webServicePort, a non-empty webServicePortTls, or at least one http/https entry among bindAddresses. If all are empty/unset, IllegalArgumentException is thrown because the broker's web service would have nowhere to listen.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/PulsarService.java:877
.attr("gitRevision", PulsarVersion.getGitSha())
.attr("gitBranch", PulsarVersion.getGitBranch())
.attr("buildUser", PulsarVersion.getBuildUser())
.attr("buildHost", PulsarVersion.getBuildHost())
.attr("buildTime", PulsarVersion.getBuildTime())
.log("Starting Pulsar Broker service");
long startTimestamp = System.currentTimeMillis(); // start time mills
mutex.lock();
try {
if (state != State.Init) {
throw new PulsarServerException("Cannot start the service once it was stopped");
}
if (config.getWebServicePort().isEmpty()
&& config.getWebServicePortTls().isEmpty()
&& BindAddressValidator.validateBindAddresses(config, Arrays.asList("http", "https")).isEmpty()) {
throw new IllegalArgumentException(
"webServicePort/webServicePortTls or http/https bindAddresses must be present");
}
if (config.isAuthorizationEnabled() && !config.isAuthenticationEnabled()) {
throw new IllegalStateException("Invalid broker configuration. Authentication must be enabled with "
+ "authenticationEnabled=true when authorization is enabled with authorizationEnabled=true.");
}
if (config.getDefaultRetentionSizeInMB() > 0
&& config.getBacklogQuotaDefaultLimitBytes() > 0
&& config.getBacklogQuotaDefaultLimitBytes()
>= (config.getDefaultRetentionSizeInMB() * 1024L * 1024L)) {
throw new IllegalArgumentException(String.format("The retention size must > the backlog quota limit "
+ "size, but the configured backlog quota limit bytes is %d, the retention size is %d",
config.getBacklogQuotaDefaultLimitBytes(),
config.getDefaultRetentionSizeInMB() * 1024L * 1024L));
}
View on GitHub (pinned to 820761864e)
Solutions
- Set webServicePort=8080 (and/or webServicePortTls=8443) in your broker config file or via environment/property override.
- Alternatively configure bindAddresses with an http (or https) entry, e.g. bindAddresses=http://0.0.0.0:8080, matching BindAddressValidator's accepted scheme.
- Check env var substitution: in containerized setups ensure the variable feeding webServicePort is actually set and non-empty.
- Run with --help/config docs to confirm the exact key names for your version (older versions used numeric 0 as 'unset').
Example fix
// before (broker.conf) webServicePort= webServicePortTls= // after webServicePort=8080 webServicePortTls=8443
Defensive patterns
Strategy: validation
Validate before calling
ServiceConfiguration cfg = new ServiceConfiguration();
PropertyUtils.loadProperties(cfg, props, /* includeHidden */ false);
boolean hasPort = cfg.getWebServicePort().isPresent() || cfg.getWebServicePortTls().isPresent();
boolean hasBindAddress = props.stringPropertyNames().stream()
.anyMatch(k -> k.startsWith("bindAddresses=") || false)
|| props.getProperty("bindAddresses", "").matches(".*(http|https)://.*");
if (!hasPort && !hasBindAddress) {
throw new IllegalArgumentException("Set webServicePort/webServicePortTls or an http/https bindAddress");
} Try / catch
try {
pulsarService.start();
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("webServicePort/webServicePortTls")) {
System.err.println("Broker config is missing an HTTP(S) listener: set webServicePort=8080 or a bindAddress");
}
throw e;
} Prevention
- Never leave both webServicePort and webServicePortTls blank; comment them out only if you add a bindAddress.
- In containers, assert required env vars (feeding webServicePort) are non-empty before startup.
- Validate configs with a pre-flight check or `pulsar broker --help`-style dry validation before deploying.
- When using bindAddresses, ensure at least one entry uses the http or https scheme.
When it happens
Trigger: Starting a broker with a ServiceConfiguration where config.getWebServicePort().isEmpty() && config.getWebServicePortTls().isEmpty() && BindAddressValidator.validateBindAddresses(config, ["http","https"]).isEmpty() — i.e. webServicePort and webServicePortTls left unset (or 0/empty) and no bindAddresses entries of type http or https configured.
Common situations: Hand-edited broker.conf / standalone.conf where ports were deleted or set to empty; copying a config that only sets tls ports but disabling TLS elsewhere; Docker/K8s env-substitution producing empty values (e.g. webServicePort=${PORT} with PORT unset); misusing bindAddresses without an http/https entry (only pulsar/https entries).
Related errors
- The retention size must > the backlog quota limit size, but
- The retention time must > the backlog quota limit time, but
- brokerDeleteInactiveTopicsEnabled and brokerCloseInactiveTop
- brokerCloseInactiveTopicsEnabled only supports brokerDeleteI
- No protocol handler is found for protocol `${protocol}`. Ava
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/22d3eaf3699ea7c5.
Report an issue: GitHub.