apache/pulsar · error · ParameterException

Quota type of 'message_age' needs a time limit

Error message

Quota type of 'message_age' needs a time limit

What it means

When the backlog quota type is message_age, the quota is defined by a time limit, so --limit-time is mandatory. The CLI throws this ParameterException when limitTimeInSec is null, since a message_age quota without a time limit is invalid.

Source

Thrown at pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdNamespaces.java:1331

                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 namespace = validateNamespace(namespaceName);

            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());
            }
            getAdmin().namespaces().setBacklogQuota(namespace, builder.build(), backlogQuotaType);
        }
    }

    @Command(description = "Remove a backlog quota policy from a namespace")
    private class RemoveBacklogQuota extends CliCommand {
        @Parameters(description = "tenant/namespace", arity = "1")
        private String namespaceName;

        @Option(names = {"-t", "--type"}, description = "Backlog quota type to remove. Valid options are: "
                + "destination_storage, message_age")
        private String backlogQuotaTypeStr = BacklogQuota.BacklogQuotaType.destination_storage.name();

        @Override
        void run() throws PulsarAdminException {

View on GitHub (pinned to 820761864e)

Solutions

  1. Add --limit-time <seconds> to the command
  2. Or, if you meant a size quota, use --backlog-quota-type destination_storage with --limit-size

Example fix

// before
pulsar-admin namespaces set-backlog-quota my-tenant/my-ns --backlog-quota-type message_age --retention-policy consumer_backlog_eviction --limit-size 1G
// after
pulsar-admin namespaces set-backlog-quota my-tenant/my-ns --backlog-quota-type message_age --retention-policy consumer_backlog_eviction --limit-time 3600
Defensive patterns

Strategy: validation

Validate before calling

// shell guard
if [ "$QUOTA_TYPE" = "message_age" ] && [ -z "$LIMIT_TIME" ]; then
  echo "--limit-time required for message_age" >&2; exit 1;
fi

Type guard

// pseudo: pair type with its required limit
if ("message_age".equals(type) && limitTimeInSec == null) {
    throw new IllegalArgumentException("--limit-time required for message_age");
}

Try / catch

try {
    admin.namespaces().setBacklogQuota(ns, quota, type);
} catch (IllegalArgumentException e) {
    // re-issue the command with --limit-time in seconds
}

Prevention

When it happens

Trigger: Running `pulsar-admin namespaces set-backlog-quota <ns> --backlog-quota-type message_age --retention-policy <policy>` without --limit-time (limitTimeInSec == null), or passing only --limit-size.

Common situations: Users copying the destination_storage example but switching the type to message_age; scripts that always set --limit-size regardless of quota type; forgetting to convert hours/minutes to seconds.

Related errors


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