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

  1. Set the policy explicitly: builder().policy(RetentionPolicy.consumer_backlog_eviction)...build()
  2. Validate quota.getPolicy() != null before calling setBacklogQuotaAsync
  3. 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

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


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