apache/pulsar · error · org.apache.pulsar.broker.admin.RestException

Exceed maximum number of topics in namespace.

Error message

Exceed maximum number of topics in namespace.

What it means

Enforced by internalCreatePartitionedTopic: creating a partitioned topic with N partitions must not push the total number of topics in the namespace above maxTopicsPerNamespace (broker.conf / namespace policy maxTopicsPerNamespace). When existing topic count + partitions exceeds the limit, creation is rejected with HTTP 412 Precondition Failed. Note partitions count as individual topics toward the quota.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/AdminResource.java:597

                    throw FutureUtil.wrapToCompletionException(ex);
                }))
                .thenCompose(policies -> {
                    int maxTopicsPerNamespace = policies != null && policies.max_topics_per_namespace != null
                            ? policies.max_topics_per_namespace : pulsar().getConfig().getMaxTopicsPerNamespace();

                    // new create check
                    if (maxTopicsPerNamespace > 0 && !pulsar().getBrokerService().isSystemTopic(topicName)) {
                        return getTopicPartitionListAsync().thenAccept(partitionedTopics -> {
                            // exclude created system topic
                            long topicsCount = partitionedTopics.stream()
                                    .filter(t -> !pulsar().getBrokerService().isSystemTopic(TopicName.get(t)))
                                    .count();
                            if (topicsCount + numPartitions > maxTopicsPerNamespace) {
                                log.error()
                                        .attr("topic", topicName)
                                        .log("Failed to create partitioned topic , exceed maximum number of topics"
                                                + " in namespace");
                                throw new RestException(Status.PRECONDITION_FAILED,
                                        "Exceed maximum number of topics in namespace.");
                            }
                        });
                    }
                    return CompletableFuture.completedFuture(null);
                })
                .thenCompose(__ -> checkTopicExistsAsync(topicName))
                .thenAccept(topicExistsInfo -> {
                    try {
                        if (topicExistsInfo.isExists()) {
                            if (topicExistsInfo.getTopicType().equals(TopicType.NON_PARTITIONED)
                                    || (topicExistsInfo.getTopicType().equals(TopicType.PARTITIONED)
                                    && !createLocalTopicOnly)) {
                                log.warn()
                                        .attr("topic", topicName)
                                        .log("Failed to create already existing topic");
                                throw new RestException(Status.CONFLICT, "This topic already exists");
                            }

View on GitHub (pinned to 820761864e)

Solutions

  1. Raise the limit: admin.namespaces().setMaxTopicsPerNamespace(...) to a value >= currentTopics + partitions (or remove the limit if set to null/0 meaning unlimited).
  2. Reduce numPartitions for the new topic so the total fits under the quota.
  3. Delete unused topics in the namespace to free quota before creating the partitioned topic.
  4. Check current usage via admin.namespaces().getMaxTopicsPerNamespace and the topics list, then plan partition counts accordingly.

Example fix

// before
admin.topics().createPartitionedTopic("my-tenant/my-ns/events", 200); // exceeds quota
// after
admin.namespaces().setMaxTopicsPerNamespace("my-tenant/my-ns", 1000);
admin.topics().createPartitionedTopic("my-tenant/my-ns/events", 200);
Defensive patterns

Strategy: validation

Validate before calling

// Java: compute headroom before creating a partitioned topic
int maxTopics = admin.namespaces().getMaxTopicsPerNamespace(ns) != null
        ? admin.namespaces().getMaxTopicsPerNamespace(ns) : Integer.MAX_VALUE;
int existing = admin.namespaces().getTopics(ns).size();
if (existing + numPartitions > maxTopics) {
    admin.namespaces().setMaxTopicsPerNamespace(ns, existing + numPartitions);
}

Try / catch

try {
    admin.topics().createPartitionedTopic(fqTopic, n);
} catch (PulsarAdminException e) {
    if (e.getStatusCode() == 412 && e.getMessage().contains("maximum number of topics")) {
        admin.namespaces().setMaxTopicsPerNamespace(ns, newLimit);
        // retry
    }
}

Prevention

When it happens

Trigger: createPartitionedTopic(t, numPartitions) where the namespace already holds many topics and topicsCount + numPartitions > maxTopicsPerNamespace; common with large partition counts (e.g. 100 partitions in a namespace near its limit) or when the maxTopicsPerNamespace policy was recently lowered.

Common situations: Namespaces provisioned with a small maxTopicsPerNamespace that later need high-partition topics; bursts of topic creation by automation exhausting the quota; lowering the policy on a populated namespace then attempting new creates.

Related errors


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