apache/pulsar · error · PulsarServerException
Topic factory failed to create topic
Error message
Topic factory failed to create topic
What it means
When a TopicFactory plugin is configured, BrokerService delegates persistent topic creation to it. If the factory throws, or returns null unexpectedly, Pulsar wraps the failure in PulsarServerException with the message 'Topic factory failed to create topic '.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/service/BrokerService.java:4619
public void recordConnectionUnthrottled() {
rateLimitedConnectionsCounter.add(1, ConnectionRateLimitOperationName.UNTHROTTLED.attributes);
throttledConnectionsGauge.dec();
}
@SuppressWarnings("unchecked")
@VisibleForTesting
public <T extends Topic> T newTopic(String topic, ManagedLedger ledger, BrokerService brokerService,
Class<T> topicClazz) throws PulsarServerException {
if (topicFactory != null) {
try {
Topic newTopic = topicFactory.create(topic, ledger, brokerService, topicClazz);
if (newTopic != null) {
return (T) newTopic;
}
} catch (Throwable e) {
log.warn().attr("topic", topic).exception(e).log("Failed to create persistent topic using factory");
throw new PulsarServerException("Topic factory failed to create topic ", e);
}
}
return topicClazz == NonPersistentTopic.class ? (T) new NonPersistentTopic(topic, BrokerService.this)
: (T) new PersistentTopic(topic, ledger, brokerService);
}
private TopicFactory createPersistentTopicFactory() throws Exception {
String topicFactoryClassName = pulsar.getConfig().getTopicFactoryClassName();
if (StringUtils.isNotBlank(topicFactoryClassName)) {
try {
return (TopicFactory) Class.forName(topicFactoryClassName)
.getDeclaredConstructor().newInstance();
} catch (Exception e) {
log.warn()
.attr("topicFactoryClassName", topicFactoryClassName)
.exception(e)
.log("Failed to initialize topic factory class");
throw e;View on GitHub (pinned to 820761864e)
Solutions
- Read the chained cause 'e' in the exception for the real failure from the factory
- Verify the topic factory plugin is compiled against the same Pulsar version and implements TopicFactory correctly
- Fix or remove the topicFactoryClassName broker configuration to fall back to the default topic implementation
- Add logging/tests in the factory to surface why create() throws or returns null
Example fix
// broker.conf // before topicFactoryClassName=com.example.MyTopicFactory // after (disable broken factory, use default implementation) #topicFactoryClassName=
Defensive patterns
Strategy: try-catch
Validate before calling
// verify factory configuration before enabling
assert brokerConfig.getTopicFactoryClassName() != null
&& Class.forName(brokerConfig.getTopicFactoryClassName()).newInstance() instanceof TopicFactory; Try / catch
try {
T topic = brokerService.getTopic(...);
} catch (PulsarServerException e) {
log.error("Topic factory failed", e.getCause());
} Prevention
- Compile custom TopicFactory plugins against the exact broker Pulsar version
- Test the factory's create() path in isolation before deploying
- Keep the factory's dependencies shaded and up to date
When it happens
Trigger: Loading a topic with a custom topic factory configured (topicFactoryClassName broker setting) where factory.create(topic, ledger, brokerService, topicClazz) throws any Throwable.
Common situations: Buggy or incompatible custom topic factory plugin (wrong Pulsar version compiled against); factory failing to allocate resources (ledger/bookkeeper errors); factory class returning null for persistent topics.
Related errors
- ${key} already exists in the dynamicConfigurationMap
- No more range can assigned to new consumer, assigned consume
- Range conflict with consumer ${conflictingConsumer}
- Error creating client for HealthChecker
- configuredService should not be an instance of SystemTopicBa
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/f4be9a166e6e9a50.
Report an issue: GitHub.