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
- Use the existing subscription rather than creating it again
- 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.