apache/pulsar · error · RestException
maxProducersPerTopic must be 0 or more
Error message
maxProducersPerTopic must be 0 or more
What it means
Thrown by internalSetMaxProducersPerTopic when the provided value is negative. The max-producers-per-topic limit is a count and must be null (unset) or >= 0. The broker rejects the update with HTTP 412 PRECONDITION_FAILED before touching the policies.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/NamespacesBase.java:2456
}
});
}
protected void internalSetDeduplicationSnapshotInterval(Integer interval) {
validateNamespacePolicyOperation(namespaceName, PolicyName.DEDUPLICATION_SNAPSHOT, PolicyOperation.WRITE);
if (interval != null && interval < 0) {
throw new RestException(Status.PRECONDITION_FAILED, "interval must be greater than or equal to 0");
}
internalSetPolicies("deduplicationSnapshotIntervalSeconds", interval);
}
protected void internalSetMaxProducersPerTopic(Integer maxProducersPerTopic) {
validateNamespacePolicyOperation(namespaceName, PolicyName.MAX_PRODUCERS, PolicyOperation.WRITE);
validatePoliciesReadOnlyAccess();
try {
if (maxProducersPerTopic != null && maxProducersPerTopic < 0) {
throw new RestException(Status.PRECONDITION_FAILED,
"maxProducersPerTopic must be 0 or more");
}
updatePolicies(namespaceName, policies -> {
policies.max_producers_per_topic = maxProducersPerTopic;
return policies;
});
log.info()
.attr("namespace", namespaceName)
.attr("maxProducersPerTopic", maxProducersPerTopic)
.log("Successfully updated maxProducersPerTopic configuration");
} catch (RestException pfe) {
throw pfe;
} catch (Exception e) {
log.error()
.attr("namespace", namespaceName)
.exception(e)
.log("Failed to update maxProducersPerTopic configuration for namespace");
throw new RestException(e);View on GitHub (pinned to 820761864e)
Solutions
- Pass 0 or a positive integer (0 means no producers allowed; null/omit means no limit)
- Use null to unset the limit instead of -1
- Add client-side validation (value == null || value >= 0) before the API call
Example fix
// before
admin.namespaces().setMaxProducersPerTopic("my-tenant/my-ns", -1); // 412
// after
admin.namespaces().setMaxProducersPerTopic("my-tenant/my-ns", null); // unset / unlimited
admin.namespaces().setMaxProducersPerTopic("my-tenant/my-ns", 100); // explicit limit Defensive patterns
Strategy: validation
Validate before calling
if (maxProducersPerTopic != null && maxProducersPerTopic < 0) {
throw new IllegalArgumentException("maxProducersPerTopic must be >= 0 or null");
} Type guard
boolean isValidCount(Integer v) { return v == null || v >= 0; } Try / catch
try {
admin.namespaces().setMaxProducersPerTopic(ns, maxProducersPerTopic);
} catch (PulsarAdminException.PreconditionFailedException e) {
log.error("Negative maxProducersPerTopic rejected: use null for unlimited");
throw e;
} Prevention
- Use null (not -1) to express 'no limit'
- Sanitize config values that may default to negative numbers
- Centralize policy-value validation in shared tooling
When it happens
Trigger: POST /namespaces/{ns}/maxProducersPerTopic with a negative integer; passing -1 intending 'unlimited' when the correct sentinel is null or 0; variable interpolation bugs in config producing negative numbers.
Common situations: Using -1 as 'no limit' (Pulsar expects null/omit); copying limits from another system with different sentinel conventions; CLI tools that don't validate input.
Related errors
- Topic name is not valid
- Partitioned Topic Name should not contain '-partition-'
- Invalid value for message TTL
- interval must be greater than or equal to 0
- maxConsumersPerTopic must be 0 or more
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/c7266ef635194dc3.
Report an issue: GitHub.