apache/flink · error · IllegalArgumentException

Segment size must be a power of 2!

Error message

Segment size must be a power of 2!

What it means

RandomAccessOutputView(MemorySegment[], int segmentSize) requires every segment to be the same size and that size to be a power of two, because it derives segmentSizeBits/segmentSizeMask from log2strict(segmentSize) and masks offsets instead of dividing. Any non-power-of-two size (e.g. 1000) fails the check (segmentSize & (segmentSize-1)) != 0 and throws IllegalArgumentException('Segment size must be a power of 2!').

Source

Thrown at flink-core/src/main/java/org/apache/flink/core/memory/RandomAccessOutputView.java:44

public class RandomAccessOutputView extends AbstractPagedOutputView
        implements SeekableDataOutputView {
    private final MemorySegment[] segments;

    private int currentSegmentIndex;

    private final int segmentSizeBits;

    private final int segmentSizeMask;

    public RandomAccessOutputView(MemorySegment[] segments, int segmentSize) {
        this(segments, segmentSize, MathUtils.log2strict(segmentSize));
    }

    public RandomAccessOutputView(MemorySegment[] segments, int segmentSize, int segmentSizeBits) {
        super(segments[0], segmentSize, 0);

        if ((segmentSize & (segmentSize - 1)) != 0) {
            throw new IllegalArgumentException("Segment size must be a power of 2!");
        }

        this.segments = segments;
        this.segmentSizeBits = segmentSizeBits;
        this.segmentSizeMask = segmentSize - 1;
    }

    @Override
    protected MemorySegment nextSegment(MemorySegment current, int positionInCurrent)
            throws EOFException {
        if (++this.currentSegmentIndex < this.segments.length) {
            return this.segments[this.currentSegmentIndex];
        } else {
            throw new EOFException();
        }
    }

    @Override

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Use a power-of-two segment size — Flink's default page size is 32 KB (32768); sizes like 4096/8192/32768/65536 all work.
  2. If the size comes from configuration, round it to the next power of two (or reject it early) before constructing the view.
  3. Ensure all MemorySegments in the array actually have that exact size; the view assumes uniform power-of-two segments.

Example fix

// before
new RandomAccessOutputView(segments, 1000); // IllegalArgumentException

// after
new RandomAccessOutputView(segments, 1024);
Defensive patterns

Strategy: validation

Validate before calling

if ((segmentSize & (segmentSize - 1)) != 0) {
    throw new IllegalArgumentException("segmentSize must be a power of 2, got " + segmentSize);
}
new RandomAccessOutputView(segments, segmentSize);

Prevention

When it happens

Trigger: Constructing a RandomAccessOutputView with a segmentSize that is not a power of two — e.g. 1000, 65536+1, or a size read from a misconfigured option; the three-arg constructor performs the same validation even if segmentSizeBits was supplied.

Common situations: Custom state/sort code copying a page size from configuration (queryable state, managed memory page sizes set to non-default values); unit tests constructing views with arbitrary round-number sizes; porting code that assumed byte-divisible segment math.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/60dc8dde585ab528. Report an issue: GitHub.