{"record":{"id":"4856cd688ab5433f","repo":"apache/pulsar","slug":"termination-of-a-partitioned-topic-is-not-allowed","errorCode":null,"errorMessage":"Termination of a partitioned topic is not allowed","messagePattern":"Termination of a partitioned 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":3993,"sourceCode":"    protected CompletableFuture<Void> internalRemoveMaxConsumers(boolean isGlobal) {\n        return pulsar().getTopicPoliciesService().updateTopicPoliciesAsync(topicName, isGlobal, true, policies -> {\n            policies.setMaxConsumerPerTopic(null);\n        });\n    }\n\n    protected CompletableFuture<MessageId> internalTerminateAsync(boolean authoritative) {\n        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(\"\");","sourceCodeStart":3975,"sourceCodeEnd":4011,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java#L3975-L4011","documentation":"internalTerminateAsync rejects termination of a partitioned topic (405): terminate must be called on individual partitions, since a partitioned topic is a metadata-only construct with no ledger of its own to truncate.","triggerScenarios":"Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java:3993 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Terminate each partition individually","Consider deleting the partitioned topic if the goal is full teardown"],"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-14T05:17:10.506Z"}