apache/pulsar · error · IllegalArgumentException

maxBytes must be >= 0

Error message

maxBytes must be >= 0

What it means

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.

Source

Thrown at pulsar-client-api-v5/src/main/java/org/apache/pulsar/client/api/v5/config/BatchingPolicy.java:60

    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;
    }

    /**
     * @return the maximum time to wait before flushing a batch
     */
    public Duration maxPublishDelay() {

View on GitHub (pinned to 820761864e)

Solutions

  1. Pass a non-negative MemorySize, e.g. MemorySize.ofBytes(128 * 1024).
  2. Fix the upstream calculation that produced the negative byte count and clamp with Math.max(0, bytes).
  3. Validate the raw config number before wrapping it in MemorySize.

Example fix

// before
BatchingPolicy bp = BatchingPolicy.builder()
    .maxSize(MemorySize.ofBytes(-1024)) // IllegalArgumentException: maxBytes must be >= 0
    .build();

// after
BatchingPolicy bp = BatchingPolicy.builder()
    .maxSize(MemorySize.ofBytes(128 * 1024))
    .build();
Defensive patterns

Strategy: validation

Validate before calling

if (bytes < 0) {
    throw new IllegalArgumentException("maxBytes must be >= 0, got: " + bytes);
}
BatchingPolicy bp = BatchingPolicy.builder().maxSize(MemorySize.ofBytes(bytes)).build();

Type guard

static boolean isValidMaxSize(MemorySize s) { return s != null && s.bytes() >= 0; }

Try / catch

try {
    bp = BatchingPolicy.builder().maxSize(MemorySize.ofBytes(bytes)).build();
} catch (IllegalArgumentException e) {
    log.warn("Invalid maxSize, using default", e);
    bp = BatchingPolicy.builder().build();
}

Prevention

When it happens

Trigger: 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.

Common situations: 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 '-'.

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


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