prestodb/presto · error · IllegalArgumentException

otherOffset %d, length %d are invalid for otherSlice with le

Error message

otherOffset %d, length %d are invalid for otherSlice with length %d

What it means

bytesEqual compares a region of this Int128 block against a byte region of another Slice. Before reading, it validates that otherOffset and length fall inside otherSlice; negative values or a range past the slice end throw IllegalArgumentException with the offending numbers.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/block/Int128ArrayBlockBuilder.java:293

     * Is the byte sequences at the {@code position + offset} position in the 128-bit values of {@code length} bytes equal
     * to the byte sequence at {@code otherOffset} in {@code otherSlice}.
     *
     * @param position The position of 128-bit integer.
     * @param offset The offset to the position in the unit of 128-bit integers.
     * For example, offset = 1 means the next position (one 128-bit integer or 16 bytes) to the specified position.
     * This means we always compare starting at 128-bit integer boundaries.
     * @param otherSlice The slice to compare to.
     * @param otherOffset The offset in bytes to the start of otherSlice.
     * @param length The length to compare in bytes. It has to be a multiple of 16.
     * @return True if the bytes are the same, false otherwise.
     */
    @Override
    public boolean bytesEqual(int position, int offset, Slice otherSlice, int otherOffset, int length)
    {
        int num128Integers = getNum128Integers(length);
        checkValidRegion(positionCount, position + offset, num128Integers);
        if (otherOffset < 0 || length < 0 || otherOffset + length > otherSlice.length()) {
            throw new IllegalArgumentException(format("otherOffset %d, length %d are invalid for otherSlice with length %d", otherOffset, length, otherSlice.length()));
        }

        int currentPosition = (position + offset + getOffsetBase()) * 2;
        for (int i = 0; i < num128Integers; i++) {
            if (values[currentPosition] != otherSlice.getLong(otherOffset) || values[currentPosition + 1] != otherSlice.getLong(otherOffset + SIZE_OF_LONG)) {
                return false;
            }

            currentPosition += 2;
            otherOffset += SIZE_OF_LONG * 2;
        }

        return true;
    }

    @Override
    public boolean mayHaveNull()
    {

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Validate otherOffset >= 0 && length >= 0 && otherOffset + length <= otherSlice.length() before calling bytesEqual.
  2. Ensure length is expressed in bytes consistent with the slice, matching the block region length.
  3. Check that otherSlice was constructed from the full expected payload (not truncated) before comparison.

Example fix

// before
block.bytesEqual(pos, 0, shortSlice, 0, 16); // throws if shortSlice.length() < 16
// after
if (shortSlice.length() >= 16) {
    block.bytesEqual(pos, 0, shortSlice, 0, 16);
}
Defensive patterns

Strategy: validation

Validate before calling

if (otherOffset < 0 || length < 0 || otherOffset + length > otherSlice.length()) {
    throw new IllegalArgumentException("otherSlice range out of bounds");
}
boolean eq = block.bytesEqual(position, offset, otherSlice, otherOffset, length);

Type guard

boolean sliceRangeValid(Slice s, int offset, int length) {
    return offset >= 0 && length >= 0 && offset + length <= s.length();
}

Try / catch

try {
    return block.bytesEqual(position, offset, otherSlice, otherOffset, length);
} catch (IllegalArgumentException e) {
    return false; // treat out-of-range region as unequal
}

Prevention

When it happens

Trigger: Calling bytesEqual(position, offset, otherSlice, otherOffset, length) where otherOffset < 0, length < 0, or otherOffset + length > otherSlice.length() — e.g. a length computed in 128-bit units but applied as bytes against a shorter slice.

Common situations: Equality/hash join comparison code passing mismatched lengths; comparing a fixed 16-byte constant slice with a length derived from the block region; corrupted or truncated slices from deserialization.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/5e4e10be6b5280af. Report an issue: GitHub.