apache/pulsar · error · RestException

Termination of a partitioned topic is not allowed

Error message

Termination of a partitioned topic is not allowed

What it means

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.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java:3993

    protected CompletableFuture<Void> internalRemoveMaxConsumers(boolean isGlobal) {
        return pulsar().getTopicPoliciesService().updateTopicPoliciesAsync(topicName, isGlobal, true, policies -> {
            policies.setMaxConsumerPerTopic(null);
        });
    }

    protected CompletableFuture<MessageId> internalTerminateAsync(boolean authoritative) {
        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("");

View on GitHub (pinned to 820761864e)

Solutions

  1. Terminate each partition individually
  2. Consider deleting the partitioned topic if the goal is full teardown
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java:3993 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/4856cd688ab5433f. Report an issue: GitHub.