{"record":{"id":"a37374efbfe10b0a","repo":"apache/pulsar","slug":"maxconsumerspertopic-must-be-0-or-more","errorCode":null,"errorMessage":"maxConsumersPerTopic must be 0 or more","messagePattern":"maxConsumersPerTopic must be 0 or more","errorType":"validation","errorClass":"RestException","httpStatus":412,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/NamespacesBase.java","lineNumber":2490,"sourceCode":"                    .exception(e)\n                    .log(\"Failed to update maxProducersPerTopic configuration for namespace\");\n            throw new RestException(e);\n        }\n    }\n\n    protected CompletableFuture<Boolean> internalGetDeduplicationAsync() {\n        return validateNamespacePolicyOperationAsync(namespaceName, PolicyName.DEDUPLICATION, PolicyOperation.READ)\n                .thenCompose(__ -> getNamespacePoliciesAsync(namespaceName))\n                .thenApply(policies -> policies.deduplicationEnabled);\n    }\n\n    protected void internalSetMaxConsumersPerTopic(Integer maxConsumersPerTopic) {\n        validateNamespacePolicyOperation(namespaceName, PolicyName.MAX_CONSUMERS, PolicyOperation.WRITE);\n        validatePoliciesReadOnlyAccess();\n\n        try {\n            if (maxConsumersPerTopic != null && maxConsumersPerTopic < 0) {\n                throw new RestException(Status.PRECONDITION_FAILED, \"maxConsumersPerTopic must be 0 or more\");\n            }\n            updatePolicies(namespaceName, policies -> {\n                policies.max_consumers_per_topic = maxConsumersPerTopic;\n                return policies;\n            });\n            log.info()\n                    .attr(\"namespace\", namespaceName)\n                    .attr(\"maxConsumersPerTopic\", maxConsumersPerTopic)\n                    .log(\"Successfully updated maxConsumersPerTopic configuration\");\n\n        } catch (RestException pfe) {\n            throw pfe;\n        } catch (Exception e) {\n            log.error()\n                    .attr(\"namespace\", namespaceName)\n                    .exception(e)\n                    .log(\"Failed to update maxConsumersPerTopic configuration for namespace\");\n            throw new RestException(e);","sourceCodeStart":2472,"sourceCodeEnd":2508,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/NamespacesBase.java#L2472-L2508","documentation":"Thrown by internalSetMaxConsumersPerTopic when the supplied value is negative. The limit is a consumer count per topic and must be null (unset) or >= 0. The update is rejected with HTTP 412 PRECONDITION_FAILED before any policy change.","triggerScenarios":"POST /namespaces/{ns}/maxConsumersPerTopic with a negative integer; passing -1 as an attempted 'unlimited' sentinel; automated policy generators emitting negative defaults.","commonSituations":"Scripts assuming -1 means unlimited; typos in numeric config; ported configs from other middleware where -1 is the conventional unlimited marker.","solutions":["Pass 0 or a positive integer","Use null (omit the parameter) to unset the limit","Validate the input client-side before calling the admin API"],"exampleFix":"// before\nadmin.namespaces().setMaxConsumersPerTopic(\"my-tenant/my-ns\", -1); // 412\n// after\nadmin.namespaces().setMaxConsumersPerTopic(\"my-tenant/my-ns\", null); // unset\nadmin.namespaces().setMaxConsumersPerTopic(\"my-tenant/my-ns\", 50);","handlingStrategy":"validation","validationCode":"if (maxConsumersPerTopic != null && maxConsumersPerTopic < 0) {\n    throw new IllegalArgumentException(\"maxConsumersPerTopic must be >= 0 or null\");\n}","typeGuard":"boolean isValidCount(Integer v) { return v == null || v >= 0; }","tryCatchPattern":"try {\n    admin.namespaces().setMaxConsumersPerTopic(ns, maxConsumersPerTopic);\n} catch (PulsarAdminException.PreconditionFailedException e) {\n    log.error(\"Negative maxConsumersPerTopic rejected: use null for unlimited\");\n    throw e;\n}","preventionTips":["Use null to unset limits","Translate -1 sentinels from other systems to null at config boundaries","Validate before API calls in automation"],"tags":["http-412","consumers","validation","admin-api"],"backgroundTag":"invalid-policy-value","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}