apache/cassandra · error · IllegalArgumentException

Length must not be negative

Error message

Length must not be negative

What it means

MmappedRegions.extend(length, chunkSize) grows the mmap windows to cover the new length; unlike map() it only rejects negative lengths, since growing to exactly 0 is tolerated and extension to a smaller-or-equal length is a no-op. A negative length indicates a caller bug (bad size accounting), so it throws IllegalArgumentException.

Solutions

  1. Pass the absolute new file length, never a negative delta; clamp with Math.max(0, size) before calling extend
  2. Re-read channel.size() immediately before extend and skip the call if it is <= current length
  3. Fix offset arithmetic that can produce negative values (unsigned/underflow bugs)
  4. Guard against concurrent truncation by checking the returned length and handling races outside extend()

Example fix

// before
long delta = newSize - oldSize;
regions.extend(delta, chunkSize); // throws when newSize < oldSize
// after
long newSize = Math.max(0, channel.size());
if (newSize > currentLength) {
    regions.extend(newSize, chunkSize);
}
Defensive patterns

Strategy: validation

Validate before calling

long newSize = Math.max(0, channel.size()); if (newSize < 0 || newSize < regions.getCurrentLength()) return; regions.extend(newSize, chunkSize);

Type guard

boolean extendable = length != null && length >= 0;

Try / catch

try { regions.extend(length, chunkSize); } catch (IllegalArgumentException e) { logger.warn("bad extend length", e); }

Prevention

When it happens

Trigger: Calling extend(length, chunkSize) with length < 0, e.g. from getOrCreate() when a computed region size underflowed, or test/test-code paths (testCopyCannotExtend, checkExtendOnCompressedChunks) passing bad sizes. Also extending after a truncate that produced negative delta math.

Common situations: Concurrent truncate-plus-extend races where a file shrinks between size() and extend(); incorrect last-segment size calculations for compressed chunks; arithmetic errors passing (newLength - offset) instead of absolute newLength.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/e11cc756c6ea9a05. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/io/util/MmappedRegions.java:144

        return new MmappedRegions(this);
    }

    private boolean isCopy()
    {
        return copy == null;
    }

    /**
     * Extends this collection of mmapped regions up to the provided total length.
     *
     * @return {@code true} if new regions have been created
     */
    public boolean extend(long length, int chunkSize)
    {
        // We cannot enforce length to be a multiple of chunkSize (at the very least the last extend on a file
        // will not satisfy this), so we hope the caller knows what they are doing.
        if (length < 0)
            throw new IllegalArgumentException("Length must not be negative");

        assert !isCopy() : "Copies cannot be extended";

        if (length <= state.length)
            return false;

        int initialRegions = state.last;
        updateState(length, chunkSize);
        copy = new State(state);
        return state.last > initialRegions;
    }

    /**
     * Extends this collection of mmapped regions up to the length of the compressed file described by the provided
     * metadata.
     *
     * @return {@code true} if new regions have been created
     */

View on GitHub (pinned to 88fd0f6a0e)