{"record":{"id":"9c730bbe73c6d156","repo":"apache/pulsar","slug":"bookkeeper-ensemble-bookkeeper-write-quoru-9c730b","errorCode":null,"errorMessage":"[--bookkeeper-ensemble], [--bookkeeper-write-quorum] and [--bookkeeper-ack-quorum] must greater than 0.","messagePattern":"\\[--bookkeeper-ensemble\\], \\[--bookkeeper-write-quorum\\] and \\[--bookkeeper-ack-quorum\\] must greater than 0\\.","errorType":"validation","errorClass":"ParameterException","httpStatus":null,"severity":"error","filePath":"pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdTopicPolicies.java","lineNumber":1274,"sourceCode":"                description = \"Throttling rate of mark-delete operation \"\n                        + \"(0 means no throttle, -1 means unset which will use \"\n                        + \"the configuration from namespace or broker)\")\n        private double managedLedgerMaxMarkDeleteRate = -1;\n\n        @Option(names = { \"--global\", \"-g\" }, description = \"Whether to set this policy globally. \"\n                + \"If set to true, the policy will be replicate to other clusters asynchronously\", arity = \"0\")\n        private boolean isGlobal = false;\n\n        @Option(names = { \"-c\",\n                \"--ml-storage-class\" },\n                description = \"Managed ledger storage class name\")\n        private String managedLedgerStorageClassName;\n\n        @Override\n        void run() throws PulsarAdminException {\n            String persistentTopic = validatePersistentTopic(topicName);\n            if (bookkeeperEnsemble <= 0 || bookkeeperWriteQuorum <= 0 || bookkeeperAckQuorum <= 0) {\n                throw new ParameterException(\"[--bookkeeper-ensemble], [--bookkeeper-write-quorum] \"\n                        + \"and [--bookkeeper-ack-quorum] must greater than 0.\");\n            }\n            getTopicPolicies(isGlobal).setPersistence(persistentTopic, new PersistencePolicies(bookkeeperEnsemble,\n                    bookkeeperWriteQuorum, bookkeeperAckQuorum, managedLedgerMaxMarkDeleteRate,\n                    managedLedgerStorageClassName));\n        }\n    }\n\n    @Command(description = \"Remove the persistence policy for a topic\")\n    private class RemovePersistence extends CliCommand {\n        @Parameters(description = \"persistent://tenant/namespace/topic\", arity = \"1\")\n        private String topicName;\n\n        @Option(names = { \"--global\", \"-g\" }, description = \"Whether to remove this policy globally. \"\n                + \"If set to true, the removing operation will be replicate to other clusters asynchronously\"\n                , arity = \"0\")\n        private boolean isGlobal = false;\n","sourceCodeStart":1256,"sourceCodeEnd":1292,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdTopicPolicies.java#L1256-L1292","documentation":"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.","triggerScenarios":"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.","commonSituations":"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'.","solutions":["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)","If you want broker defaults, remove the topic-level persistence policy instead of passing zeros"],"exampleFix":"// before\npulsar-admin topics set-persistence my-topic --bookkeeper-ensemble 0 --bookkeeper-write-quorum 3 --bookkeeper-ack-quorum 2\n// after\npulsar-admin topics set-persistence my-topic --bookkeeper-ensemble 3 --bookkeeper-write-quorum 3 --bookkeeper-ack-quorum 2","handlingStrategy":"validation","validationCode":"if (ensemble <= 0 || writeQuorum <= 0 || ackQuorum <= 0) {\n    throw new IllegalArgumentException(\"ensemble/writeQuorum/ackQuorum must all be > 0\");\n}\nif (!(ensemble >= writeQuorum && writeQuorum >= ackQuorum)) {\n    throw new IllegalArgumentException(\"require ensemble >= writeQuorum >= ackQuorum\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Enforce ensemble >= write-quorum >= ack-quorum in your tooling","Do not pass 0 to mean 'broker default'; unset the policy instead","Source quorum numbers from a validated config, not raw shell arithmetic"],"tags":["cli","pulsar-admin","argument-validation","persistence"],"backgroundTag":"invalid-argument-value","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}