apache/pulsar · error · RestException
Termination of a non-persistent topic is not allowed
Error message
Termination of a non-persistent topic is not allowed
What it means
internalTerminateAsync rejects termination of non-persistent topics (405): termination means permanently stopping a persistent managed ledger and returning its last message id, which is meaningless for non-persistent topics.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java:4000
if (SystemTopicNames.isSystemTopic(topicName)) {
return FutureUtil.failedFuture(new RestException(Status.METHOD_NOT_ALLOWED,
"Termination of a system topic is not allowed"));
}
return validateTopicOperationAsync(topicName, TopicOperation.TERMINATE)
.thenCompose(__ -> validateGlobalNamespaceOwnershipAsync(namespaceName))
.thenCompose(__ -> validateTopicOwnershipAsync(topicName, authoritative))
.thenCompose(__ -> getPartitionedTopicMetadataAsync(topicName, authoritative, false))
.thenAccept(partitionMetadata -> {
if (partitionMetadata.partitions > 0) {
throw new RestException(Status.METHOD_NOT_ALLOWED,
"Termination of a partitioned topic is not allowed");
}
})
.thenCompose(__ -> getTopicReferenceAsync(topicName))
.thenCompose(topic -> {
if (!(topic instanceof PersistentTopic)) {
throw new RestException(Status.METHOD_NOT_ALLOWED,
"Termination of a non-persistent topic is not allowed");
}
return ((PersistentTopic) topic).terminate();
});
}
protected void internalTerminatePartitionedTopic(AsyncResponse asyncResponse, boolean authoritative) {
if (topicName.isPartitioned()) {
String msg = "Termination of a non-partitioned topic is not allowed using partitioned-terminate"
+ ", please use terminate commands";
log.error().attr("topic", topicName).attr("msg", msg).log("");
asyncResponse.resume(new RestException(Status.METHOD_NOT_ALLOWED, msg));
return;
}
validateTopicOperationAsync(topicName, TopicOperation.TERMINATE)
.thenCompose(__ -> validateGlobalNamespaceOwnershipAsync(namespaceName))
.thenCompose(unused -> getPartitionedTopicMetadataAsync(topicName, authoritative, false))
.thenAccept(partitionMetadata -> {View on GitHub (pinned to 820761864e)
Solutions
- Delete the non-persistent topic instead of terminating it
- Switch to a persistent topic if termination semantics are required
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java:4000 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/d466792e3990178e.
Report an issue: GitHub.