apache/pulsar · error · IllegalArgumentException

bytes must be >= 0

Error message

bytes must be >= 0

What it means

MemorySize is a record whose compact constructor validates that the byte count is non-negative; it represents sizes (batch limits, buffer sizes) where negative values are meaningless. Any attempt to construct MemorySize with a negative long throws IllegalArgumentException. This check also backs BatchingPolicy's maxSize validation.

Source

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

package org.apache.pulsar.client.api.v5.config;

/**
 * A type-safe representation of a memory size in bytes.
 *
 * <p>Use the static factory methods to create instances from common units:
 * <pre>{@code
 * MemorySize.ofMegabytes(64)   // 64 MB
 * MemorySize.ofGigabytes(1)    // 1 GB
 * MemorySize.ofKilobytes(512)  // 512 KB
 * }</pre>
 *
 * @param bytes the size in bytes
 */
public record MemorySize(long bytes) {

    public MemorySize {
        if (bytes < 0) {
            throw new IllegalArgumentException("bytes must be >= 0");
        }
    }

    private static final long KB = 1024;
    private static final long MB = 1024 * KB;
    private static final long GB = 1024 * MB;

    /**
     * Create a memory size from a number of bytes.
     *
     * @param bytes the size in bytes
     * @return a {@link MemorySize} representing the specified number of bytes
     */
    public static MemorySize ofBytes(long bytes) {
        return new MemorySize(bytes);
    }

    /**

View on GitHub (pinned to 820761864e)

Solutions

  1. Pass a non-negative byte count: new MemorySize(128 * 1024).
  2. Fix the upstream computation and clamp: Math.max(0, bytes).
  3. For 'unset' use Optional or omit the setting instead of a negative sentinel.

Example fix

// before
MemorySize size = new MemorySize(-1); // IllegalArgumentException: bytes must be >= 0

// after
MemorySize size = new MemorySize(128 * 1024);
Defensive patterns

Strategy: validation

Validate before calling

if (bytes < 0) {
    throw new IllegalArgumentException("bytes must be >= 0, got: " + bytes);
}
MemorySize size = new MemorySize(bytes);

Type guard

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

Try / catch

try {
    size = new MemorySize(bytes);
} catch (IllegalArgumentException e) {
    log.warn("Negative size, clamping to 0", e);
    size = new MemorySize(0);
}

Prevention

When it happens

Trigger: Calling new MemorySize(-1), MemorySize.ofBytes(-n), or any factory/conversion that receives a negative byte count; storing a 'remaining quota' that went negative directly into MemorySize.

Common situations: Subtraction-based accounting underflow; unit conversion mistakes (MiB vs bytes with overflow wrapping negative is rare but possible with huge longs); config values with a stray minus sign.

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/754751ef9aad1f09. Report an issue: GitHub.