apache/pulsar · error · IllegalArgumentException
the attribute policy cannot be null
Error message
the attribute policy cannot be null
What it means
BacklogQuota.validate() (called when setting a backlog quota via the admin API, e.g. setBacklogQuotaAsync) throws IllegalArgumentException if the quota's policy field is null. A BacklogQuota without a policy is considered invalid because the broker must know how to enforce the quota.
Source
Thrown at pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/policies/data/BacklogQuota.java:94
}
/**
* Enumeration type determines how to retain backlog against the resource shortages.
*/
enum RetentionPolicy {
/** Policy which holds producer's send request until the resource becomes available (or holding times out). */
producer_request_hold,
/** Policy which throws javax.jms.ResourceAllocationException to the producer. */
producer_exception,
/** Policy which evicts the oldest message from the slowest consumer's backlog. */
consumer_backlog_eviction,
}
default void validate() {
if (getPolicy() == null) {
throw new IllegalArgumentException("the attribute policy cannot be null");
}
}
}
View on GitHub (pinned to 820761864e)
Solutions
- Set the policy explicitly: builder().policy(RetentionPolicy.consumer_backlog_eviction)...build()
- Validate quota.getPolicy() != null before calling setBacklogQuotaAsync
- Check the source JSON/config that the policy field is present and correctly named
Example fix
// before
BacklogQuota quota = BacklogQuotaImpl.builder().limitSize(1_000_000_000L).build();
admin.namespaces().setBacklogQuotaAsync(ns, quota);
// after
BacklogQuota quota = BacklogQuotaImpl.builder()
.limitSize(1_000_000_000L)
.policy(RetentionPolicy.consumer_backlog_eviction)
.build();
admin.namespaces().setBacklogQuotaAsync(ns, quota); Defensive patterns
Strategy: validation
Validate before calling
if (quota.getPolicy() == null) {
throw new IllegalArgumentException("backlog quota policy must be set before submitting");
} Try / catch
try {
admin.namespaces().setBacklogQuotaAsync(ns, quota).get();
} catch (ExecutionException e) {
if (e.getCause() instanceof IllegalArgumentException) { /* fix quota policy */ }
} Prevention
- Always use BacklogQuotaImpl.builder() and set policy explicitly
- Validate deserialized quota objects before sending to admin API
- Check JSON configs include the policy field
When it happens
Trigger: Calling namespacePolicies().setBacklogQuotaAsync(...) (or builder paths) with a BacklogQuota built without setting policy — e.g. BacklogQuotaImpl.builder().limitSize(...).build() omitting policy.
Common situations: Programmatically constructing BacklogQuota from deserialized partial data (missing policy in JSON), copying config where the policy key was omitted, default-constructed quota objects passed directly to the admin API.
Understand the failure class
Background: "X is required", "field cannot be empty", error-the-field-is-required: missing required-field validation errors, explained — this error's family across 39 libraries.
Related errors
- failoverThreshold must be larger than 0
- recoverThreshold must be larger than 0
- checkHealthyIntervalMs must be larger than 0
- testTopic can not be blank
- pulsarServiceUrlArray can not be empty
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/a8312c6add60a758.
Report an issue: GitHub.