apache/pulsar · error · ParameterException
Invalid backlog quota type '%s'. Valid options are: %s
Error message
Invalid backlog quota type '%s'. Valid options are: %s
What it means
pulsar-admin's set-backlog-quota topic policy command parses the --quota-type (or backlogQuotaType) argument with BacklogQuota.BacklogQuotaType.valueOf(). When the supplied string does not match an enum constant exactly, the IllegalArgumentException is rethrown as a JCommander ParameterException listing the valid options. It is pure client-side argument validation before any request reaches the broker.
Source
Thrown at pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdTopicPolicies.java:1061
@Option(names = { "--global", "-g" }, description = "Whether to set this policy globally. "
+ "If set to true, the policy will be replicate to other clusters asynchronously")
private boolean isGlobal = false;
@Override
void run() throws PulsarAdminException {
BacklogQuota.RetentionPolicy policy;
BacklogQuota.BacklogQuotaType backlogQuotaType;
try {
policy = BacklogQuota.RetentionPolicy.valueOf(policyStr);
} catch (IllegalArgumentException e) {
throw new ParameterException(String.format("Invalid retention policy type '%s'. Valid options are: %s",
policyStr, Arrays.toString(BacklogQuota.RetentionPolicy.values())));
}
try {
backlogQuotaType = BacklogQuota.BacklogQuotaType.valueOf(backlogQuotaTypeStr);
} catch (IllegalArgumentException e) {
throw new ParameterException(String.format("Invalid backlog quota type '%s'. Valid options are: %s",
backlogQuotaTypeStr, Arrays.toString(BacklogQuota.BacklogQuotaType.values())));
}
String persistentTopic = validatePersistentTopic(topicName);
BacklogQuota.Builder builder = BacklogQuota.builder().retentionPolicy(policy);
if (backlogQuotaType == BacklogQuota.BacklogQuotaType.destination_storage) {
// set quota by storage size
if (limit == null) {
throw new ParameterException("Quota type of 'destination_storage' needs a size limit");
}
builder.limitSize(limit);
} else {
// set quota by time
if (limitTimeInSec == null) {
throw new ParameterException("Quota type of 'message_age' needs a time limit");
}
builder.limitTime(limitTimeInSec.intValue());
}View on GitHub (pinned to 820761864e)
Solutions
- Use one of the exact enum constants printed in the error message: destination_storage or message_age
- Check the enum constants with: org.apache.pulsar.common.policies.data.BacklogQuota.BacklogQuotaType
- For size-based limits use 'destination_storage' with --limit; for time-based use 'message_age' with --limitTime
Example fix
// before pulsar-admin topics set-backlog-quota my-topic --quota-type DestinationStorage --limit 10G // after pulsar-admin topics set-backlog-quota my-topic --quota-type destination_storage --limit 10G
Defensive patterns
Strategy: validation
Validate before calling
final Set<String> VALID = Arrays.stream(BacklogQuota.BacklogQuotaType.values()).map(Enum::name).collect(Collectors.toSet());
if (!VALID.contains(quotaType)) throw new IllegalArgumentException("quotaType must be one of " + VALID + ", got: " + quotaType); Type guard
static boolean isValidBacklogQuotaType(String s) {
return Arrays.stream(BacklogQuota.BacklogQuotaType.values()).anyMatch(t -> t.name().equals(s));
} Prevention
- Use tab-completion or --help to list valid quota types before invoking
- Keep quota type strings in a constants file shared by scripts
- Remember names are exact snake_case enum constants, case-sensitive
When it happens
Trigger: Running 'pulsar-admin topics set-backlog-quota <topic> --quota-type <bad-value>' where <bad-value> is misspelled, wrong-cased (e.g. 'Destination_Storage' or 'destination-storage'), or a value valid in a different enum (e.g. retention policy names like 'producer_exception').
Common situations: Copy-pasting examples from older documentation or other systems (Kafka/Disk-usage quota names); scripts written before the 'message_age' type was introduced; shell scripts with a typo or camelCase vs snake_case confusion; passing a retention policy name in the quota-type slot.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Illegal subscription type %s. Possible values: %s.
- delete mode can only be set to delete_when_no_subscriptions
- --offloadedReadPriority parameter must be one of ${validValu
- Need to provide a persistent topic name
- Need to provide a non-persistent topic name
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/5383221a61fc8271.
Report an issue: GitHub.