apache/pulsar · error · ParameterException

[--bookkeeper-ensemble], [--bookkeeper-write-quorum] and [--

Error message

[--bookkeeper-ensemble], [--bookkeeper-write-quorum] and [--bookkeeper-ack-quorum] must greater than 0.

What it means

The set-persistence topic policy command validates that the BookKeeper ensemble, write quorum, and ack quorum values are all greater than zero before constructing PersistencePolicies. Any value <= 0 is rejected with this ParameterException, since such quorum configurations are meaningless for BookKeeper writes.

Source

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

                description = "Throttling rate of mark-delete operation "
                        + "(0 means no throttle, -1 means unset which will use "
                        + "the configuration from namespace or broker)")
        private double managedLedgerMaxMarkDeleteRate = -1;

        @Option(names = { "--global", "-g" }, description = "Whether to set this policy globally. "
                + "If set to true, the policy will be replicate to other clusters asynchronously", arity = "0")
        private boolean isGlobal = false;

        @Option(names = { "-c",
                "--ml-storage-class" },
                description = "Managed ledger storage class name")
        private String managedLedgerStorageClassName;

        @Override
        void run() throws PulsarAdminException {
            String persistentTopic = validatePersistentTopic(topicName);
            if (bookkeeperEnsemble <= 0 || bookkeeperWriteQuorum <= 0 || bookkeeperAckQuorum <= 0) {
                throw new ParameterException("[--bookkeeper-ensemble], [--bookkeeper-write-quorum] "
                        + "and [--bookkeeper-ack-quorum] must greater than 0.");
            }
            getTopicPolicies(isGlobal).setPersistence(persistentTopic, new PersistencePolicies(bookkeeperEnsemble,
                    bookkeeperWriteQuorum, bookkeeperAckQuorum, managedLedgerMaxMarkDeleteRate,
                    managedLedgerStorageClassName));
        }
    }

    @Command(description = "Remove the persistence policy for a topic")
    private class RemovePersistence extends CliCommand {
        @Parameters(description = "persistent://tenant/namespace/topic", arity = "1")
        private String topicName;

        @Option(names = { "--global", "-g" }, description = "Whether to remove this policy globally. "
                + "If set to true, the removing operation will be replicate to other clusters asynchronously"
                , arity = "0")
        private boolean isGlobal = false;

View on GitHub (pinned to 820761864e)

Solutions

  1. Set all three flags to positive integers, respecting ensemble >= write-quorum >= ack-quorum (e.g. --bookkeeper-ensemble 3 --bookkeeper-write-quorum 3 --bookkeeper-ack-quorum 2)
  2. If you want broker defaults, remove the topic-level persistence policy instead of passing zeros

Example fix

// before
pulsar-admin topics set-persistence my-topic --bookkeeper-ensemble 0 --bookkeeper-write-quorum 3 --bookkeeper-ack-quorum 2
// after
pulsar-admin topics set-persistence my-topic --bookkeeper-ensemble 3 --bookkeeper-write-quorum 3 --bookkeeper-ack-quorum 2
Defensive patterns

Strategy: validation

Validate before calling

if (ensemble <= 0 || writeQuorum <= 0 || ackQuorum <= 0) {
    throw new IllegalArgumentException("ensemble/writeQuorum/ackQuorum must all be > 0");
}
if (!(ensemble >= writeQuorum && writeQuorum >= ackQuorum)) {
    throw new IllegalArgumentException("require ensemble >= writeQuorum >= ackQuorum");
}

Prevention

When it happens

Trigger: Running set-persistence with --bookkeeper-ensemble, --bookkeeper-write-quorum, or --bookkeeper-ack-quorum set to 0, a negative number, or an unset/zero-default flag.

Common situations: Flag defaults left at 0 in a script; users computing quorum values with a failing shell arithmetic expression; copy-paste of partial examples omitting one of the three quorum flags; automation that passes 0 to mean 'use broker default'.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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