apache/pulsar · error · IllegalArgumentException
maxMessages must be >= 0
Error message
maxMessages must be >= 0
What it means
The private BatchingPolicy constructor (reached via its builder) requires maxMessages to be non-negative, since it caps how many messages may be accumulated in a single batch. A negative value is nonsensical as a cap, so the library throws IllegalArgumentException at construction time.
Source
Thrown at pulsar-client-api-v5/src/main/java/org/apache/pulsar/client/api/v5/config/BatchingPolicy.java:57
private static final Duration DEFAULT_MAX_PUBLISH_DELAY = Duration.ofMillis(1);
private static final int DEFAULT_MAX_MESSAGES = 1000;
private static final MemorySize DEFAULT_MAX_SIZE = MemorySize.ofKilobytes(128);
private static final BatchingPolicy DISABLED =
new BatchingPolicy(false, DEFAULT_MAX_PUBLISH_DELAY, DEFAULT_MAX_MESSAGES, DEFAULT_MAX_SIZE);
private final boolean enabled;
private final Duration maxPublishDelay;
private final int maxMessages;
private final MemorySize maxSize;
private BatchingPolicy(boolean enabled, Duration maxPublishDelay, int maxMessages, MemorySize maxSize) {
if (maxPublishDelay == null) {
maxPublishDelay = DEFAULT_MAX_PUBLISH_DELAY;
}
Objects.requireNonNull(maxSize, "maxSize must not be null");
if (maxMessages < 0) {
throw new IllegalArgumentException("maxMessages must be >= 0");
}
if (maxSize.bytes() < 0) {
throw new IllegalArgumentException("maxBytes must be >= 0");
}
this.enabled = enabled;
this.maxPublishDelay = maxPublishDelay;
this.maxMessages = maxMessages;
this.maxSize = maxSize;
}
/**
* @return whether batching is enabled
*/
public boolean enabled() {
return enabled;
}
/**View on GitHub (pinned to 820761864e)
Solutions
- Pass 0 or a positive number to maxMessages; use 0 if you want to disable message-count-based batching.
- If -1 is your 'unset' sentinel, map it to the builder default (omit the maxMessages call).
- Validate the value at config load time: Math.max(0, configuredValue) or reject the config.
Example fix
// before
BatchingPolicy bp = BatchingPolicy.builder()
.maxMessages(-1) // IllegalArgumentException
.build();
// after
BatchingPolicy bp = BatchingPolicy.builder()
.maxMessages(1000) // or omit to use the default
.build(); Defensive patterns
Strategy: validation
Validate before calling
if (maxMessages < 0) {
throw new IllegalArgumentException("maxMessages must be >= 0, got: " + maxMessages);
}
BatchingPolicy bp = BatchingPolicy.builder().maxMessages(maxMessages).build(); Type guard
static boolean isValidMaxMessages(int v) { return v >= 0; } Try / catch
try {
bp = BatchingPolicy.builder().maxMessages(cfg).build();
} catch (IllegalArgumentException e) {
log.warn("Invalid maxMessages, using default batching", e);
bp = BatchingPolicy.builder().build();
} Prevention
- Never use -1 as an 'unset' sentinel; omit the builder call or use Optional instead.
- Clamp computed batch sizes with Math.max(0, value).
- Check the sign of any value derived from quota/limit arithmetic.
When it happens
Trigger: Calling BatchingPolicy.builder().maxMessages(n) with n < 0, or invoking the private constructor via a factory with a negative maxMessages argument, e.g. maxMessages(-1).
Common situations: Computing the batch size from a formula that can go negative (e.g. remaining quota subtraction); parsing a config value with a stray minus sign; a defaulting routine that uses -1 as a sentinel for 'unset' instead of 0 or Optional.
Understand the failure class
Background: "Invalid configuration value" and "Unsupported/Unknown setting value" errors: why libraries reject your config strings, numbers, and types — this error's family across 30 libraries.
Related errors
- maxBytes must be >= 0
- chunkSize must be > 0 when chunking is enabled
- configuredService should not be an instance of SystemTopicBa
- The shared resource doesn't support thread pool configurati
- No resources have been configured while using shareConfigure
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/11edae4bbd7578cd.
Report an issue: GitHub.