apache/pulsar · error · RuntimeException

Failed to initialize controller for

Error message

Failed to initialize controller for ${topic}

What it means

ScalableTopicService.getOrCreateController asynchronously creates and initializes a per-topic controller. If controller.initialize() fails, the stored future is evicted from the cache so callers can retry, and the failure is rethrown wrapped in a RuntimeException naming the topic, preserving the original cause.

Solutions

  1. Inspect the cause chain (getCause()) for the real initialization failure
  2. Retry the operation — the failed future is evicted so a fresh controller is built
  3. Check topic metadata/storage health for the named topic; unload the topic to reset state

Example fix

// handling
try {
    controller = service.getOrCreateController(topic).join();
} catch (CompletionException e) {
    log.warn("controller init failed for {}", topic, e.getCause()); // retry later
}
Defensive patterns

Strategy: retry

Validate before calling

if (!topicExists(topic)) { throw new IllegalStateException("Topic " + topic + " must exist before controller use"); }

Try / catch

try {
    controller = service.getOrCreateController(topic).join();
} catch (CompletionException e) {
    Throwable cause = e.getCause();
    log.warn("Controller init failed for {}, will retry", topic, cause); // failure was evicted, retry is safe
}

Prevention

When it happens

Trigger: Any of the callers (splitSegment, rebucketSegment, mergeSegments, create/deleteSubscription, seekSubscription) triggers getOrCreateController for a topic whose controller initialization throws (metadata load failure, storage error, etc.).

Common situations: Topic metadata corrupted or unavailable in the underlying store; broker under contention; a prior initialization left transient state that the retry now succeeds on (hence the eviction-for-retry design).

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/7bb537cae997f557. Report an issue: GitHub.

Appendix: source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/service/scalable/ScalableTopicService.java:111

    // --- Controller management ---

    /**
     * Get or create a controller for a scalable topic. The controller will attempt
     * leader election; only the leader actively coordinates consumers.
     */
    public CompletableFuture<ScalableTopicController> getOrCreateController(TopicName topic) {
        String key = topic.toString();
        CompletableFuture<ScalableTopicController> stored = controllers.computeIfAbsent(key, k -> {
            ScalableTopicController controller = new ScalableTopicController(
                    topic, resources, brokerService, coordinationService);
            return controller.initialize().thenApply(__ -> controller);
        });
        // Evict failed futures so subsequent callers can retry. This runs *outside*
        // computeIfAbsent, so modifying the map here is safe.
        return stored.exceptionally(ex -> {
            controllers.remove(key, stored);
            throw new RuntimeException("Failed to initialize controller for " + topic, ex);
        });
    }

    /**
     * Release the controller for a topic (e.g., on topic unload).
     */
    public CompletableFuture<Void> releaseController(TopicName topic) {
        CompletableFuture<ScalableTopicController> future = controllers.remove(topic.toString());
        if (future != null) {
            return future.thenCompose(ScalableTopicController::close);
        }
        return CompletableFuture.completedFuture(null);
    }

    // --- Admin operations ---

    /**
     * Create a new scalable topic with the given number of initial segments.

View on GitHub (pinned to 820761864e)