apache/pulsar · warning · RestException

Examine messages on a partitioned topic is not allowed, plea

Error message

Examine messages on a partitioned topic is not allowed, please try examine message on specific topic partition

What it means

The 'examine messages' admin operation (verifies a topic's latest messages can be read) does not work on a partitioned topic's base name; examination applies per partition. If the topic name is not already a partition and metadata shows partitions > 0, the broker throws 405 METHOD_NOT_ALLOWED with this message.

Source

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

                    entry.release();
                }
            }
        });
    }

    protected CompletableFuture<Response> internalExamineMessageAsync(String initialPosition, long messagePosition,
                                                                      boolean authoritative) {
        long messagePositionLocal = messagePosition < 1 ? 1 : messagePosition;
        String initialPositionLocal = initialPosition == null ? "latest" : initialPosition;
        return validateTopicOperationAsync(topicName, TopicOperation.PEEK_MESSAGES)
        .thenCompose(__ -> validateGlobalNamespaceOwnershipAsync(namespaceName))
        .thenCompose(__ -> validateTopicOwnershipAsync(topicName, authoritative))
        .thenCompose(__ -> {
            if (!topicName.isPartitioned()) {
                return getPartitionedTopicMetadataAsync(topicName, authoritative, false)
                        .thenCompose(partitionedTopicMetadata -> {
                            if (partitionedTopicMetadata.partitions > 0) {
                                throw new RestException(Status.METHOD_NOT_ALLOWED,
                                        "Examine messages on a partitioned topic is not allowed, "
                                                + "please try examine message on specific topic partition");
                            } else {
                                return CompletableFuture.completedFuture(null);
                            }
                        });
            }
            return CompletableFuture.completedFuture(null);
        }).thenCompose(__ -> getTopicReferenceAsync(topicName))
        .thenCompose(topic -> {
            if (!(topic instanceof PersistentTopic)) {
                log.error()
                        .attr("topic", topicName)
                        .log("Not supported operation of non-persistent topic");
                throw new RestException(Status.METHOD_NOT_ALLOWED,
                        "Examine messages on a non-persistent topic is not allowed");
            }
            try {

View on GitHub (pinned to 820761864e)

Solutions

  1. Run examine on each concrete partition (my-topic-partition-N)
  2. Enumerate partitions via the partitions endpoint and loop examine calls per partition
  3. Skip partitioned base names in bulk examine tooling, or expand them to partitions first

Example fix

// before
admin.topics().examineMessages("persistent://public/default/my-topic");
// after
for (String part : admin.topics().getPartitionedPartitions("persistent://public/default/my-topic")) {
    admin.topics().examineMessages(part);
}
Defensive patterns

Strategy: validation

Validate before calling

PartitionedTopicMetadata md = admin.topics().getPartitionedMetadata(topic);
if (md.partitions > 0) { /* examine each partition instead */ }

Type guard

boolean isPartitionName(String topic) { return topic.matches(".*-partition-\\d+$"); }

Prevention

When it happens

Trigger: GET /admin/v2/persistent/{tenant}/{namespace}/{topic}/examinemessages (or examineMessages call) with a partitioned topic base name instead of my-topic-partition-N.

Common situations: CI health checks that enumerate partitioned topics by base name; operators running examine across a namespace without resolving partitions.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/f6aeadab307c762d. Report an issue: GitHub.