{"record":{"id":"d466792e3990178e","repo":"apache/pulsar","slug":"termination-of-a-non-persistent-topic-is-not-allow","errorCode":null,"errorMessage":"Termination of a non-persistent topic is not allowed","messagePattern":"Termination of a non-persistent topic is not allowed","errorType":"http","errorClass":"RestException","httpStatus":405,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java","lineNumber":4000,"sourceCode":"        if (SystemTopicNames.isSystemTopic(topicName)) {\n            return FutureUtil.failedFuture(new RestException(Status.METHOD_NOT_ALLOWED,\n                    \"Termination of a system topic is not allowed\"));\n        }\n\n        return validateTopicOperationAsync(topicName, TopicOperation.TERMINATE)\n        .thenCompose(__ -> validateGlobalNamespaceOwnershipAsync(namespaceName))\n        .thenCompose(__ -> validateTopicOwnershipAsync(topicName, authoritative))\n        .thenCompose(__ -> getPartitionedTopicMetadataAsync(topicName, authoritative, false))\n        .thenAccept(partitionMetadata -> {\n            if (partitionMetadata.partitions > 0) {\n                throw new RestException(Status.METHOD_NOT_ALLOWED,\n                        \"Termination of a partitioned topic is not allowed\");\n            }\n        })\n        .thenCompose(__ -> getTopicReferenceAsync(topicName))\n        .thenCompose(topic -> {\n            if (!(topic instanceof PersistentTopic)) {\n                throw new RestException(Status.METHOD_NOT_ALLOWED,\n                        \"Termination of a non-persistent topic is not allowed\");\n            }\n            return ((PersistentTopic) topic).terminate();\n        });\n    }\n\n    protected void internalTerminatePartitionedTopic(AsyncResponse asyncResponse, boolean authoritative) {\n        if (topicName.isPartitioned()) {\n            String msg = \"Termination of a non-partitioned topic is not allowed using partitioned-terminate\"\n                    + \", please use terminate commands\";\n            log.error().attr(\"topic\", topicName).attr(\"msg\", msg).log(\"\");\n            asyncResponse.resume(new RestException(Status.METHOD_NOT_ALLOWED, msg));\n            return;\n        }\n        validateTopicOperationAsync(topicName, TopicOperation.TERMINATE)\n        .thenCompose(__ -> validateGlobalNamespaceOwnershipAsync(namespaceName))\n        .thenCompose(unused -> getPartitionedTopicMetadataAsync(topicName, authoritative, false))\n        .thenAccept(partitionMetadata -> {","sourceCodeStart":3982,"sourceCodeEnd":4018,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java#L3982-L4018","documentation":"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.","triggerScenarios":"Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java:4000 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Delete the non-persistent topic instead of terminating it","Switch to a persistent topic if termination semantics are required"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}