apache/pulsar · error · RestException
Subscription not found
Error message
Subscription not found
What it means
HTTP 404 returned when deleting a subscription across all partitions of a partitioned topic. Each partition's delete is attempted and the results aggregated; if any partition throws NotFoundException (the subscription cursor does not exist there), the broker surfaces 'Subscription not found'. This means the named subscription does not (fully) exist on the topic's partitions.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java:1718
if (partitionMetadata.partitions > 0) {
final List<CompletableFuture<Void>> futures = new ArrayList<>();
PulsarAdmin adminClient;
try {
adminClient = pulsar().getAdminClient();
} catch (PulsarServerException e) {
return CompletableFuture.failedFuture(e);
}
for (int i = 0; i < partitionMetadata.partitions; i++) {
TopicName topicNamePartition = topicName.getPartition(i);
futures.add(adminClient.topics()
.deleteSubscriptionAsync(topicNamePartition.toString(), subName, force));
}
return FutureUtil.waitForAll(futures).handle((result, exception) -> {
if (exception != null) {
Throwable t = exception.getCause();
if (t instanceof NotFoundException) {
throw new RestException(Status.NOT_FOUND,
"Subscription not found");
} else if (t instanceof PreconditionFailedException) {
throw new RestException(Status.PRECONDITION_FAILED,
"Subscription has active connected consumers");
} else {
throw new RestException(t);
}
}
return null;
});
}
return internalDeleteSubscriptionForNonPartitionedTopicAsync(subName, authoritative, force);
});
}
});
}
// Note: this method expects the caller to check authorizationView on GitHub (pinned to 820761864e)
Solutions
- Check existing subscriptions with `pulsar-admin topics subscriptions <topic>` and correct the subscription name.
- Treat 404 as success in idempotent unsubscribe flows (catch and continue).
- If the subscription exists on some partitions only, delete it per-partition (topic-partition-N) or recreate it and delete again to converge.
- Review auto-delete policies (namespace/topic subscription expiration) that may remove idle subscriptions.
Example fix
// before
admin.topics().deleteSubscription("persistent://t/ns/topic", "my-sub"); // 404 if already gone
// after
try {
admin.topics().deleteSubscription("persistent://t/ns/topic", "my-sub");
} catch (PulsarAdminException.NotFoundException e) {
// already unsubscribed; ignore
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!admin.topics().getSubscriptions(topic).contains(subName)) {
return; // nothing to unsubscribe
}
admin.topics().deleteSubscription(topic, subName); Try / catch
try {
admin.topics().deleteSubscription(topic, subName);
} catch (PulsarAdminException.NotFoundException e) {
// subscription already gone; idempotent success
} Prevention
- Make unsubscribe flows idempotent
- Check subscriptions list before deletion
- Review subscription auto-expiration policies that remove idle subs
When it happens
Trigger: DELETE /admin/v2/persistent/{ns}/{topic}/subscription/{subName} (or `pulsar-admin topics unsubscribe`) where the subscription was already deleted, never created, or exists on some partitions but not all of a partitioned topic.
Common situations: Double unsubscribe from client code or automation; subscription auto-deleted after its last consumer disconnected (allowAutoSubscriptionDeletion / inactive deletion policies); partially-created subscription during a failed previous operation; typo in subscription name.
Related errors
- Subscription has active connected consumers
- getSubNotFoundErrorMessage(topicName.toString(), subName)
- cluster data is required
- Cannot delete non empty namespace
- Namespace does not exist
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/993d9f6d0e48f4a4.
Report an issue: GitHub.