{"record":{"id":"ac63254d78d44918","repo":"apache/pulsar","slug":"maxbytes-must-be-0","errorCode":null,"errorMessage":"maxBytes must be >= 0","messagePattern":"maxBytes must be >= 0","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-client-api-v5/src/main/java/org/apache/pulsar/client/api/v5/config/BatchingPolicy.java","lineNumber":60,"sourceCode":"\n    private static final BatchingPolicy DISABLED =\n            new BatchingPolicy(false, DEFAULT_MAX_PUBLISH_DELAY, DEFAULT_MAX_MESSAGES, DEFAULT_MAX_SIZE);\n\n    private final boolean enabled;\n    private final Duration maxPublishDelay;\n    private final int maxMessages;\n    private final MemorySize maxSize;\n\n    private BatchingPolicy(boolean enabled, Duration maxPublishDelay, int maxMessages, MemorySize maxSize) {\n        if (maxPublishDelay == null) {\n            maxPublishDelay = DEFAULT_MAX_PUBLISH_DELAY;\n        }\n        Objects.requireNonNull(maxSize, \"maxSize must not be null\");\n        if (maxMessages < 0) {\n            throw new IllegalArgumentException(\"maxMessages must be >= 0\");\n        }\n        if (maxSize.bytes() < 0) {\n            throw new IllegalArgumentException(\"maxBytes must be >= 0\");\n        }\n        this.enabled = enabled;\n        this.maxPublishDelay = maxPublishDelay;\n        this.maxMessages = maxMessages;\n        this.maxSize = maxSize;\n    }\n\n    /**\n     * @return whether batching is enabled\n     */\n    public boolean enabled() {\n        return enabled;\n    }\n\n    /**\n     * @return the maximum time to wait before flushing a batch\n     */\n    public Duration maxPublishDelay() {","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-api-v5/src/main/java/org/apache/pulsar/client/api/v5/config/BatchingPolicy.java#L42-L78","documentation":"The BatchingPolicy constructor also validates that maxSize.bytes() >= 0, since maxSize caps the total serialized size of a batch. MemorySize itself rejects negative values (see MemorySize), but this guard re-checks after construction so a negative byte count can never become a batching limit. The library throws IllegalArgumentException at construction time.","triggerScenarios":"Constructing a MemorySize with a negative long and passing it into the BatchingPolicy builder's maxSize(...), e.g. MemorySize.ofBytes(-1024), or a builder path that stores bytes and bypasses MemorySize's own check.","commonSituations":"Subtracting usage from a limit and letting the value go negative; unit-conversion bugs (KB vs bytes) producing negative numbers; config values parsed with a leading '-'.","solutions":["Pass a non-negative MemorySize, e.g. MemorySize.ofBytes(128 * 1024).","Fix the upstream calculation that produced the negative byte count and clamp with Math.max(0, bytes).","Validate the raw config number before wrapping it in MemorySize."],"exampleFix":"// before\nBatchingPolicy bp = BatchingPolicy.builder()\n    .maxSize(MemorySize.ofBytes(-1024)) // IllegalArgumentException: maxBytes must be >= 0\n    .build();\n\n// after\nBatchingPolicy bp = BatchingPolicy.builder()\n    .maxSize(MemorySize.ofBytes(128 * 1024))\n    .build();","handlingStrategy":"validation","validationCode":"if (bytes < 0) {\n    throw new IllegalArgumentException(\"maxBytes must be >= 0, got: \" + bytes);\n}\nBatchingPolicy bp = BatchingPolicy.builder().maxSize(MemorySize.ofBytes(bytes)).build();","typeGuard":"static boolean isValidMaxSize(MemorySize s) { return s != null && s.bytes() >= 0; }","tryCatchPattern":"try {\n    bp = BatchingPolicy.builder().maxSize(MemorySize.ofBytes(bytes)).build();\n} catch (IllegalArgumentException e) {\n    log.warn(\"Invalid maxSize, using default\", e);\n    bp = BatchingPolicy.builder().build();\n}","preventionTips":["Clamp byte accounting so subtracting usage never yields negatives before constructing MemorySize.","Double-check unit conversions (KB/MB/bytes) feeding maxSize.","Validate size config at load time, before client construction."],"tags":["java","configuration","illegal-argument","batching","memory-size"],"backgroundTag":"invalid-configuration-value","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}