apache/pulsar · error · IllegalArgumentException
brokerDeleteInactiveTopicsEnabled and brokerCloseInactiveTop
Error message
brokerDeleteInactiveTopicsEnabled and brokerCloseInactiveTopicsEnabled are mutually exclusive. Enable at most one of them.
What it means
This IllegalArgumentException is thrown at broker startup when both brokerDeleteInactiveTopicsEnabled and brokerCloseInactiveTopicsEnabled are set to true. The two features are alternative ways of reclaiming inactive topics (deleting vs closing/unloading them), so enabling both is contradictory and the broker refuses to start rather than picking one arbitrarily.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/PulsarService.java:907
>= (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));
}
if (config.getDefaultRetentionTimeInMinutes() > 0
&& config.getBacklogQuotaDefaultLimitSecond() > 0
&& config.getBacklogQuotaDefaultLimitSecond() >= config.getDefaultRetentionTimeInMinutes() * 60) {
throw new IllegalArgumentException(String.format("The retention time must > the backlog quota limit "
+ "time, but the configured backlog quota limit time duration is %d, "
+ "the retention time duration is %d",
config.getBacklogQuotaDefaultLimitSecond(),
config.getDefaultRetentionTimeInMinutes() * 60));
}
if (config.isBrokerDeleteInactiveTopicsEnabled() && config.isBrokerCloseInactiveTopicsEnabled()) {
throw new IllegalArgumentException(
"brokerDeleteInactiveTopicsEnabled and brokerCloseInactiveTopicsEnabled are mutually "
+ "exclusive. Enable at most one of them.");
}
if (config.isBrokerCloseInactiveTopicsEnabled()
&& config.getBrokerDeleteInactiveTopicsMode()
!= InactiveTopicDeleteMode.delete_when_no_subscriptions) {
throw new IllegalArgumentException(
"brokerCloseInactiveTopicsEnabled only supports brokerDeleteInactiveTopicsMode="
+ "delete_when_no_subscriptions. Under delete_when_subscriptions_caught_up a topic "
+ "whose subscriptions are caught up is inactive even while consumers are still "
+ "connected, so closing it would repeatedly unload and reload the topic.");
}
openTelemetryTopicStats = new OpenTelemetryTopicStats(this);
openTelemetryConsumerStats = new OpenTelemetryConsumerStats(this);
openTelemetryProducerStats = new OpenTelemetryProducerStats(this);
openTelemetryReplicatorStats = new OpenTelemetryReplicatorStats(this);View on GitHub (pinned to 820761864e)
Solutions
- Disable one of the two flags: set brokerDeleteInactiveTopicsEnabled=false if you want closing, or brokerCloseInactiveTopicsEnabled=false if you want deletion.
- Decide based on goal: use delete to remove inactive topics entirely, use close to unload them (with a grace period) while keeping metadata.
- Audit broker.conf, env-var overrides, and framework templates so only one flag is set to true.
- Restart the broker and confirm startup passes validation.
Example fix
// before (broker.conf) brokerDeleteInactiveTopicsEnabled=true brokerCloseInactiveTopicsEnabled=true // after brokerDeleteInactiveTopicsEnabled=false brokerCloseInactiveTopicsEnabled=true
Defensive patterns
Strategy: validation
Validate before calling
// before broker start (Java)
if (conf.isBrokerDeleteInactiveTopicsEnabled() && conf.isBrokerCloseInactiveTopicsEnabled()) {
throw new IllegalArgumentException(
"Enable at most one of brokerDeleteInactiveTopicsEnabled / brokerCloseInactiveTopicsEnabled");
} Try / catch
try {
pulsar.start();
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("brokerDeleteInactiveTopicsEnabled and brokerCloseInactiveTopicsEnabled are mutually exclusive")) {
// fix broker.conf: set exactly one of the two flags to true, then retry
} else {
throw e;
}
} Prevention
- Enable at most one of the two inactive-topic flags in any broker config template.
- Search Helm charts/env files for both keys when upgrading brokers.
- Prefer brokerCloseInactiveTopicsEnabled for unload-style reclamation; otherwise use the delete flag.
- Document the chosen policy in your deployment repo so future edits don't re-enable both.
When it happens
Trigger: Starting a broker with isBrokerDeleteInactiveTopicsEnabled()==true AND isBrokerCloseInactiveTopicsEnabled()==true in the service configuration, e.g. after enabling the newer close-inactive-topics feature without disabling the legacy delete flag.
Common situations: Configuration merges or version upgrades where a new brokerCloseInactiveTopicsEnabled=true line is added while the older brokerDeleteInactiveTopicsEnabled=true is left in place; templated Helm/env config that sets both flags.
Related errors
- brokerCloseInactiveTopicsEnabled only supports brokerDeleteI
- webServicePort/webServicePortTls or http/https bindAddresses
- The retention size must > the backlog quota limit size, but
- The retention time must > the backlog quota limit time, but
- No protocol handler is found for protocol `${protocol}`. Ava
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/3162a1491db95b55.
Report an issue: GitHub.