apache/pulsar · error · IllegalArgumentException
The load shedding strategy: ${loadBalancerLoadSheddingStrate
Error message
The load shedding strategy: ${loadBalancerLoadSheddingStrategy} can't work with the placement strategy: ${loadBalancerLoadPlacementStrategy} What it means
ModularLoadManagerImpl.initialize instantiates the configured placement strategy; if that class also implements LoadSheddingStrategy, the same instance is used for both placement and shedding, which is only allowed when loadBalancerLoadSheddingStrategy and loadBalancerLoadPlacementStrategy name the same class. Otherwise initialize throws IllegalArgumentException at broker startup.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/impl/ModularLoadManagerImpl.java:273
sheddingExcludedNamespaceSelectionStrategy = new RoundRobinBrokerSelector();
policies = new SimpleResourceAllocationPolicies(pulsar);
filterPipeline.add(new BrokerLoadManagerClassFilter());
filterPipeline.add(new BrokerVersionFilter());
LoadManagerShared.refreshBrokerToFailureDomainMap(pulsar, brokerToFailureDomainMap);
// register listeners for domain changes
pulsarResources.getClusterResources().getFailureDomainResources()
.registerListener(__ -> {
executors.execute(
() -> LoadManagerShared.refreshBrokerToFailureDomainMap(pulsar, brokerToFailureDomainMap));
});
if (placementStrategy instanceof LoadSheddingStrategy) {
// if the placement strategy is also a load shedding strategy
// we need to check two strategies are the same
if (!conf.getLoadBalancerLoadSheddingStrategy().equals(
conf.getLoadBalancerLoadPlacementStrategy())) {
throw new IllegalArgumentException("The load shedding strategy: "
+ conf.getLoadBalancerLoadSheddingStrategy()
+ " can't work with the placement strategy: "
+ conf.getLoadBalancerLoadPlacementStrategy());
}
// bind the load shedding strategy and the placement strategy
loadSheddingStrategy = (LoadSheddingStrategy) placementStrategy;
} else {
loadSheddingStrategy = createLoadSheddingStrategy();
}
}
public void handleDataNotification(Notification t) {
if (t.getPath().startsWith(LoadManager.LOADBALANCE_BROKERS_ROOT)) {
brokersData.listLocks(LoadManager.LOADBALANCE_BROKERS_ROOT)
.thenAccept(brokers -> {
reapDeadBrokerPreallocations(brokers);
});
View on GitHub (pinned to 820761864e)
Solutions
- Make both properties reference the same strategy class, e.g. set loadBalancerLoadSheddingStrategy and loadBalancerLoadPlacementStrategy to the same FQN.
- Or revert loadBalancerLoadPlacementStrategy to a pure placement strategy that does not implement LoadSheddingStrategy (e.g. the default).
- Remove the custom combined strategy and use the standard shedding/placement pair.
- Validate the two config values together in deployment tooling before rollout.
Example fix
# before loadBalancerLoadPlacementStrategy=org.apache.pulsar.broker.loadbalance.impl.MinimizeMemoryPlacementStrategyThatAlsoSheds loadBalancerLoadSheddingStrategy=org.apache.pulsar.broker.loadbalance.impl.ThresholdShedder # after (same class for both, or a pure placement strategy) loadBalancerLoadPlacementStrategy=org.apache.pulsar.broker.loadbalance.impl.MinimizeMemoryPlacementStrategyThatAlsoSheds loadBalancerLoadSheddingStrategy=org.apache.pulsar.broker.loadbalance.impl.MinimizeMemoryPlacementStrategyThatAlsoSheds
Defensive patterns
Strategy: validation
Validate before calling
Class<?> placement = Class.forName(conf.getLoadBalancerLoadPlacementStrategy());
if (LoadSheddingStrategy.class.isAssignableFrom(placement)
&& !conf.getLoadBalancerLoadSheddingStrategy()
.equals(conf.getLoadBalancerLoadPlacementStrategy())) {
throw new IllegalArgumentException("Shedding and placement strategies must match when placement sheds");
} Type guard
boolean isCombinedStrategy(String placementClass) {
try { return LoadSheddingStrategy.class.isAssignableFrom(Class.forName(placementClass)); }
catch (ClassNotFoundException e) { return false; }
} Try / catch
try {
new ModularLoadManagerImpl(pulsar, coordinator, checkOwnershipRequired);
} catch (IllegalArgumentException e) {
log.error("Load manager config invalid: {}", e.getMessage());
// fail startup clearly instead of masking the config mistake
} Prevention
- When placement strategy implements LoadSheddingStrategy, always set both config keys to the identical FQN.
- Diff both properties together when copying configs between clusters.
- Smoke-test broker startup with production service configuration before rollout.
When it happens
Trigger: Broker starts with loadBalancerLoadPlacementStrategy set to a class that implements LoadSheddingStrategy while loadBalancerLoadSheddingStrategy names a different class (default placement is NOT a shedding strategy, so this needs deliberate config).
Common situations: Operators copy configs between clusters and change only one of the two properties; custom placement strategies that implement both interfaces; typos where one property got a shedding class and the other kept the default.
Related errors
- Configuration field 'transactionPendingAckBatchedWriteMaxDel
- 'transactionLogBatchedWriteMaxRecords' value must be greater
- 'transactionLogBatchedWriteMaxSize' value must be greater th
- 'transactionLogBatchedWriteMaxDelayInMillis' value must be g
- No authorization providers are present.
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/876a577f3b85f148.
Report an issue: GitHub.