apache/pulsar · error · RestException

Subscription already exists for topic

Error message

Subscription already exists for topic

What it means

While creating a subscription, the broker found the subscription name already exists on the topic (durable subscription already registered), so the create request is rejected with 409 Conflict instead of replacing the existing subscription.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java:2496

            AsyncResponse asyncResponse, String subscriptionName,
            MessageIdImpl targetMessageId, boolean authoritative, boolean replicated,
            Map<String, String> properties) {

        validateTopicOwnershipAsync(topicName, authoritative)
                .thenCompose(__ -> validateTopicOperationAsync(topicName, TopicOperation.SUBSCRIBE, subscriptionName))
                .thenCompose(__ -> pulsar().getBrokerService().isAllowAutoTopicCreationAsync(topicName))
                .thenCompose(isAllowAutoTopicCreation -> pulsar().getBrokerService()
                        .getTopic(topicName.toString(), isAllowAutoTopicCreation))
                .thenApply(optTopic -> {
                    if (optTopic.isPresent()) {
                        return optTopic.get();
                    } else {
                        throw new RestException(Status.PRECONDITION_FAILED,
                                "Topic does not exist and cannot be auto-created");
                    }
        }).thenCompose(topic -> {
            if (topic.getSubscriptions().containsKey(subscriptionName)) {
                throw new RestException(Status.CONFLICT, "Subscription already exists for topic");
            }

            return topic.createSubscription(subscriptionName, InitialPosition.Latest, replicated, properties);
        }).thenCompose(subscription -> {
            // Mark the cursor as "inactive" as it was created without a real consumer connected
            ((PersistentSubscription) subscription).deactivateCursor();
            return subscription.resetCursor(
                    PositionFactory.create(targetMessageId.getLedgerId(), targetMessageId.getEntryId()));
        }).thenRun(() -> {
            log.info()
                    .attr("topic", topicName)
                    .attr("subscription", subscriptionName)
                    .attr("messageId", targetMessageId)
                    .log("Successfully created subscription at message id");
            asyncResponse.resume(Response.noContent().build());
        }).exceptionally(ex -> {
            Throwable t = (ex instanceof CompletionException ? ex.getCause() : ex);
            if (!(t instanceof WebApplicationException)) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Use the existing subscription rather than creating it again
  2. Delete the subscription first if it must be recreated (durable subscription data is lost)
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java:2496 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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