apache/pulsar · error · IllegalArgumentException
configuredService should not be an instance of SystemTopicBa
Error message
configuredService should not be an instance of SystemTopicBasedTopicPoliciesService
What it means
LegacyAwareTopicPoliciesService wraps a configured TopicPoliciesService and delegates to the system-topic service. Passing a SystemTopicBasedTopicPoliciesService as the configuredService is invalid (it would recursively wrap itself), so the constructor throws IllegalArgumentException.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/service/LegacyAwareTopicPoliciesService.java:70
SystemTopicBasedTopicPoliciesService systemTopicService,
TopicPoliciesService configuredService) {
// Generally, we only need to check if the __change_events topic exists once because the __change_events topic
// should only be created by broker before the upgrade, where `SystemTopicBasedTopicPoliciesService` is
// configured as the topic policies service.
this.isLegacyNamespace = Caffeine.newBuilder().expireAfterWrite(Duration.ofHours(1))
.buildAsync(new AsyncCacheLoader<>() {
@NonNull
@Override
public CompletableFuture<? extends Boolean> asyncLoad(NamespaceName key,
@NonNull Executor executor) {
return NamespaceEventsSystemTopicFactory.checkSystemTopicExists(key, EventType.TOPIC_POLICY,
pulsar);
}
});
this.systemTopicService = systemTopicService;
this.configuredService = configuredService;
if (configuredService instanceof SystemTopicBasedTopicPoliciesService) {
throw new IllegalArgumentException(
"configuredService should not be an instance of SystemTopicBasedTopicPoliciesService");
}
}
@Override
public void start(PulsarService pulsarService) {
// We should not call `systemTopicService.start()`, which just registers a namespace bundle listener to create
// a reader on `<namespace>/__change_events` when the namespace's bundle is loaded firstly. It's just an
// optimization to create the reader before loading any topic. However, it could create a reader on a namespace
// that does not even have the __change_events topic.
configuredService.start(pulsarService);
}
@Override
public void close() throws Exception {
try {
configuredService.close();
} finally {View on GitHub (pinned to 820761864e)
Solutions
- Pass the legacy/in-memory TopicPoliciesService (e.g. InMemoryTopicPoliciesService) as configuredService, not the system-topic one
- Swap the constructor arguments if systemTopicService and configuredService were mixed up
- Update broker extension code to the current TopicPoliciesService wiring API
Example fix
// before new LegacyAwareTopicPoliciesService(pulsar, systemTopicService, systemTopicService); // after new LegacyAwareTopicPoliciesService(pulsar, systemTopicService, new InMemoryTopicPoliciesService());
Defensive patterns
Strategy: type-guard
Validate before calling
if (configuredService instanceof SystemTopicBasedTopicPoliciesService) {
throw new IllegalArgumentException("pass the legacy service as configuredService");
} Type guard
boolean isValidConfiguredService(TopicPoliciesService s) {
return !(s instanceof SystemTopicBasedTopicPoliciesService);
} Try / catch
try {
new LegacyAwareTopicPoliciesService(pulsar, systemTopicService, configuredService);
} catch (IllegalArgumentException e) {
log.error("Wrong TopicPoliciesService wiring", e);
} Prevention
- Follow current Pulsar broker startup wiring order for topic policy services
- Add instanceof assertions in extension code before constructing
- Re-check wiring code after Pulsar upgrades
When it happens
Trigger: Programmatically constructing LegacyAwareTopicPoliciesService(pulsar, systemTopicService, configuredService) where configuredService instanceof SystemTopicBasedTopicPoliciesService.
Common situations: Custom broker extension code wiring topic policy services in the wrong order (passing the system-topic service as the legacy/base service); misreading constructor parameter order; plugin configuration code written for an older Pulsar version.
Related errors
- ${key} already exists in the dynamicConfigurationMap
- The shared resource doesn't support thread pool configurati
- No resources have been configured while using shareConfigure
- jitterPercent must be in [0, 100]
- maxMessages must be >= 0
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/ead63184b32a92d1.
Report an issue: GitHub.