apache/pulsar · error · RestException

getTopicNotFoundErrorMessage(topicName.toString())

Error message

getTopicNotFoundErrorMessage(topicName.toString())

What it means

HTTP 404 thrown by getPropertiesAsync (used by the topic-properties admin API) when getTopicIfExists returns empty, i.e. no persistent topic is loaded/existing under the given name on this broker. The endpoint reads managed-ledger properties, which only exist for an actual PersistentTopic, so a missing topic yields NOT_FOUND with the standard 'topic not found' message.

Source

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

                .thenCompose(__ -> {
                    if (topicName.isPartitioned()) {
                        return getPropertiesAsync();
                    }
                    return pulsar().getBrokerService().fetchPartitionedTopicMetadataAsync(topicName)
                            .thenCompose(metadata -> {
                                if (metadata.partitions == 0) {
                                    return getPropertiesAsync();
                                }
                                return CompletableFuture.completedFuture(metadata.properties);
                            });
                });
    }

    private CompletableFuture<Map<String, String>> getPropertiesAsync() {
        return pulsar().getBrokerService().getTopicIfExists(topicName.toString())
                .thenApply(opt -> {
                    if (!opt.isPresent()) {
                        throw new RestException(Status.NOT_FOUND,
                                getTopicNotFoundErrorMessage(topicName.toString()));
                    }
                    return ((PersistentTopic) opt.get()).getManagedLedger().getProperties();
        });
    }

    protected CompletableFuture<Void> internalUpdatePropertiesAsync(boolean authoritative,
                                                                    Map<String, String> properties) {
        if (properties == null || properties.isEmpty()) {
            log.warn()
                    .attr("topic", topicName)
                    .log("properties is empty, ignore update");
            return CompletableFuture.completedFuture(null);
        }
        return validateTopicOperationAsync(topicName, TopicOperation.UPDATE_METADATA)
                .thenCompose(__ -> validateTopicOwnershipAsync(topicName, authoritative))
                .thenCompose(__ -> {
                    if (topicName.isPartitioned()) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Verify the topic exists: `pulsar-admin topics list <namespace>` or `pulsar-admin topics stats`, create it if missing.
  2. Ensure you query the exact partition name (e.g. topic-partition-0) for persistent topics, or the partitioned parent for its own properties.
  3. Confirm your client targets the correct cluster/service URL so the lookup/redirect resolves to the owning broker.
  4. Recreate the topic if it was deleted and properties are needed afterwards.

Example fix

// before
GET /admin/v2/persistent/my-tenant/my-ns/my-topic/properties
// after (query an existing partition)
GET /admin/v2/persistent/my-tenant/my-ns/my-topic-partition-0/properties
Defensive patterns

Strategy: try-catch

Validate before calling

if (!admin.topics().getList(namespace).contains(topic)) {
    throw new IllegalStateException("Topic " + topic + " does not exist");
}
Map<String,String> props = admin.topics().getProperties(topic);

Try / catch

try {
    return admin.topics().getProperties(topic);
} catch (PulsarAdminException.NotFoundException e) {
    return Collections.emptyMap();
}

Prevention

When it happens

Trigger: GET /admin/v2/persistent/{ns}/{topic}/properties on a topic that does not exist, was already deleted, or is only present as partitioned metadata without the individual partition loaded.

Common situations: Querying properties of a deleted topic; hitting a broker that does not own the topic without redirection (wrong service URL); typo in topic name; topic exists but partitions were never created.

Related errors


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