{"record":{"id":"d33011219ed46194","repo":"apache/pulsar","slug":"configuration-field-transactionpendingackbatchedw","errorCode":null,"errorMessage":"Configuration field 'transactionPendingAckBatchedWriteMaxRecords' value must be greater than or equal to 10","messagePattern":"Configuration field 'transactionPendingAckBatchedWriteMaxRecords' value must be greater than or equal to 10","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/validator/TransactionBatchedWriteValidator.java","lineNumber":28,"sourceCode":" *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.apache.pulsar.broker.validator;\n\nimport org.apache.pulsar.broker.ServiceConfiguration;\n\npublic class TransactionBatchedWriteValidator {\n\n    public static void validate(ServiceConfiguration configuration){\n        if (configuration.isTransactionPendingAckBatchedWriteEnabled()){\n            if (configuration.getTransactionPendingAckBatchedWriteMaxRecords() < 10){\n                throw new IllegalArgumentException(\"Configuration field \"\n                        + \"'transactionPendingAckBatchedWriteMaxRecords' value must be greater than or equal to 10\");\n            }\n            if (configuration.getTransactionPendingAckBatchedWriteMaxSize() < 1024 * 128){\n                throw new IllegalArgumentException(\"Configuration field \"\n                        + \"'transactionPendingAckBatchedWriteMaxSize' value must be greater than or equal to 128k\");\n            }\n            if (configuration.getTransactionPendingAckBatchedWriteMaxDelayInMillis() < 1){\n                throw new IllegalArgumentException(\"Configuration field \"\n                        + \"'transactionPendingAckBatchedWriteMaxDelayInMillis' value must be greater than or equal to\"\n                        + \" 1\");\n            }\n        }\n        if (configuration.isTransactionLogBatchedWriteEnabled()){\n            if (configuration.getTransactionLogBatchedWriteMaxRecords() < 10){\n                throw new IllegalArgumentException(\"Configuration field \"\n                        + \"'transactionLogBatchedWriteMaxRecords' value must be greater than or equal to 10\");\n            }\n            if (configuration.getTransactionLogBatchedWriteMaxSize() < 1024 * 128){","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/validator/TransactionBatchedWriteValidator.java#L10-L46","documentation":"TransactionBatchedWriteValidator.validate enforces startup configuration constraints for transaction pending-ack batched writes. When transactionPendingAckBatchedWriteEnabled is true, transactionPendingAckBatchedWriteMaxRecords must be at least 10; otherwise it throws IllegalArgumentException. This prevents configuring batches too small to be useful.","triggerScenarios":"Starting a broker with transactionPendingAckBatchedWriteEnabled=true and transactionPendingAckBatchedWriteMaxRecords set to a value < 10 (e.g. 1, 5, or unset/0).","commonSituations":"Enabling pending-ack batched writes in broker.conf/standalone.conf but copying a sample config with a small maxRecords value; typos leaving the value at 0; ops scripts templating the field incorrectly.","solutions":["Set transactionPendingAckBatchedWriteMaxRecords to a value >= 10 (e.g. 500)","If you don't want batching constraints, set transactionPendingAckBatchedWriteEnabled=false","Check broker.conf / Kubernetes values.yaml for an overridden or empty value","Run ./gradlew sanityCheck or start with the validator locally to catch other related limits (maxSize >= 128k, maxDelay >= 1)"],"exampleFix":"// before (broker.conf)\ntransactionPendingAckBatchedWriteEnabled=true\ntransactionPendingAckBatchedWriteMaxRecords=5\n// after\ntransactionPendingAckBatchedWriteEnabled=true\ntransactionPendingAckBatchedWriteMaxRecords=500","handlingStrategy":"validation","validationCode":"public static void checkPendingAckBatchedWriteConfig(ServiceConfiguration conf) {\n    if (conf.isTransactionPendingAckBatchedWriteEnabled()\n            && conf.getTransactionPendingAckBatchedWriteMaxRecords() < 10) {\n        throw new IllegalArgumentException(\n            \"transactionPendingAckBatchedWriteMaxRecords must be >= 10 when batched write is enabled\");\n    }\n}\n// Call TransactionBatchedWriteValidator.validate(config) at startup before serving traffic.","typeGuard":null,"tryCatchPattern":"try {\n    TransactionBatchedWriteValidator.validate(config);\n} catch (IllegalArgumentException e) {\n    log.fatal(\"Invalid transaction batched-write config: {}\", e.getMessage());\n    System.exit(1); // fail startup fast\n}","preventionTips":["Pin transactionPendingAckBatchedWriteMaxRecords >= 10 in config templates and Helm values","Run TransactionBatchedWriteValidator.validate() in CI against your broker.conf","Re-check config after enabling transactionPendingAckBatchedWriteEnabled","Keep documented defaults in broker.conf rather than blank values"],"tags":["configuration","transaction","validation"],"backgroundTag":"invalid-broker-configuration","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"}