{"record":{"id":"8f1134851d2f94c7","repo":"apache/pulsar","slug":"exceed-maximum-number-of-topics-in-namespace","errorCode":null,"errorMessage":"Exceed maximum number of topics in namespace.","messagePattern":"Exceed maximum number of topics in namespace\\.","errorType":"http","errorClass":"org.apache.pulsar.broker.admin.RestException","httpStatus":412,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/AdminResource.java","lineNumber":597,"sourceCode":"                    throw FutureUtil.wrapToCompletionException(ex);\n                }))\n                .thenCompose(policies -> {\n                    int maxTopicsPerNamespace = policies != null && policies.max_topics_per_namespace != null\n                            ? policies.max_topics_per_namespace : pulsar().getConfig().getMaxTopicsPerNamespace();\n\n                    // new create check\n                    if (maxTopicsPerNamespace > 0 && !pulsar().getBrokerService().isSystemTopic(topicName)) {\n                        return getTopicPartitionListAsync().thenAccept(partitionedTopics -> {\n                            // exclude created system topic\n                            long topicsCount = partitionedTopics.stream()\n                                    .filter(t -> !pulsar().getBrokerService().isSystemTopic(TopicName.get(t)))\n                                    .count();\n                            if (topicsCount + numPartitions > maxTopicsPerNamespace) {\n                                log.error()\n                                        .attr(\"topic\", topicName)\n                                        .log(\"Failed to create partitioned topic , exceed maximum number of topics\"\n                                                + \" in namespace\");\n                                throw new RestException(Status.PRECONDITION_FAILED,\n                                        \"Exceed maximum number of topics in namespace.\");\n                            }\n                        });\n                    }\n                    return CompletableFuture.completedFuture(null);\n                })\n                .thenCompose(__ -> checkTopicExistsAsync(topicName))\n                .thenAccept(topicExistsInfo -> {\n                    try {\n                        if (topicExistsInfo.isExists()) {\n                            if (topicExistsInfo.getTopicType().equals(TopicType.NON_PARTITIONED)\n                                    || (topicExistsInfo.getTopicType().equals(TopicType.PARTITIONED)\n                                    && !createLocalTopicOnly)) {\n                                log.warn()\n                                        .attr(\"topic\", topicName)\n                                        .log(\"Failed to create already existing topic\");\n                                throw new RestException(Status.CONFLICT, \"This topic already exists\");\n                            }","sourceCodeStart":579,"sourceCodeEnd":615,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/AdminResource.java#L579-L615","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Raise the limit: admin.namespaces().setMaxTopicsPerNamespace(...) to a value >= currentTopics + partitions (or remove the limit if set to null/0 meaning unlimited).","Reduce numPartitions for the new topic so the total fits under the quota.","Delete unused topics in the namespace to free quota before creating the partitioned topic.","Check current usage via admin.namespaces().getMaxTopicsPerNamespace and the topics list, then plan partition counts accordingly."],"exampleFix":"// before\nadmin.topics().createPartitionedTopic(\"my-tenant/my-ns/events\", 200); // exceeds quota\n// after\nadmin.namespaces().setMaxTopicsPerNamespace(\"my-tenant/my-ns\", 1000);\nadmin.topics().createPartitionedTopic(\"my-tenant/my-ns/events\", 200);","handlingStrategy":"validation","validationCode":"// Java: compute headroom before creating a partitioned topic\nint maxTopics = admin.namespaces().getMaxTopicsPerNamespace(ns) != null\n        ? admin.namespaces().getMaxTopicsPerNamespace(ns) : Integer.MAX_VALUE;\nint existing = admin.namespaces().getTopics(ns).size();\nif (existing + numPartitions > maxTopics) {\n    admin.namespaces().setMaxTopicsPerNamespace(ns, existing + numPartitions);\n}","typeGuard":null,"tryCatchPattern":"try {\n    admin.topics().createPartitionedTopic(fqTopic, n);\n} catch (PulsarAdminException e) {\n    if (e.getStatusCode() == 412 && e.getMessage().contains(\"maximum number of topics\")) {\n        admin.namespaces().setMaxTopicsPerNamespace(ns, newLimit);\n        // retry\n    }\n}","preventionTips":["Budget partitions into your maxTopicsPerNamespace planning — each partition counts.","Monitor topic counts per namespace and alert at ~80% of quota.","Avoid lowering the quota on namespaces that already exceed it.","Prefer fewer, higher-volume topics over very high partition counts when near the limit."],"tags":["http-412","quota","partitioned-topic","admin-api"],"backgroundTag":"topic-quota-exceeded","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}