prestodb/presto · error · GenericInternalException
Value %d is less than MIN_INT
Error message
Value %d is less than MIN_INT
What it means
IntegerType.writeLong's underflow branch: a long value below Integer.MIN_VALUE (-2147483648) cannot be cast to int without wraparound, so it throws GenericInternalException 'Value %d is less than MIN_INT' to prevent silent truncation of the block data.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/type/IntegerType.java:51
@Override
public Object getObjectValue(SqlFunctionProperties properties, Block block, int position)
{
if (block.isNull(position)) {
return null;
}
return block.getInt(position);
}
@Override
public final void writeLong(BlockBuilder blockBuilder, long value)
{
if (value > Integer.MAX_VALUE) {
throw new GenericInternalException(format("Value %d exceeds MAX_INT", value));
}
else if (value < Integer.MIN_VALUE) {
throw new GenericInternalException(format("Value %d is less than MIN_INT", value));
}
blockBuilder.writeInt((int) value).closeEntry();
}
@Override
@SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
public boolean equals(Object other)
{
return other == INTEGER;
}
@Override
public int hashCode()
{
return getClass().hashCode();
}
}View on GitHub (pinned to 55bb57d202)
Solutions
- Range-check the value against Integer.MIN_VALUE before writing; write NULL on underflow
- Cast via SQL CAST to INTEGER for well-defined overflow behavior at the engine level
- Widen the target column to BIGINT for values that legitimately go below int range
- Fix sentinel/marker values in upstream data to fit int range
Example fix
// before
integerBlockBuilder.writeLong(negativeBigint); // throws when < MIN_INT
// after
if (negativeBigint < Integer.MIN_VALUE || negativeBigint > Integer.MAX_VALUE) {
integerBlockBuilder.appendNull();
} else {
integerBlockBuilder.writeLong(negativeBigint);
} Defensive patterns
Strategy: type-guard
Validate before calling
public static boolean fitsInInt(long value) {
return value >= Integer.MIN_VALUE && value <= Integer.MAX_VALUE;
}
// check specifically for negatives: if (v < Integer.MIN_VALUE) -> NULL or BIGINT column Type guard
public static Integer toIntOrNull(Long value) {
return (value == null || value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) ? null : value.intValue();
} Try / catch
try {
integerBlockBuilder.writeLong(value);
} catch (GenericInternalException e) {
integerBlockBuilder.appendNull(); // underflow: NULL out or escalate
} Prevention
- Watch for large negative sentinel values in source data
- Keep negative epoch math on BIGINT, not INTEGER columns
- Apply Ints.checkedCast-style checks at ETL boundaries
When it happens
Trigger: Writing a long < -2147483648 via IntegerType's writeLong; negative BIGINT values (e.g. huge negative ids, timestamps in ms before 1970 by centuries) funneled into an INTEGER writer.
Common situations: BIGINT→INTEGER table copies; sentinel negative values (-1L<<40) used as 'unset' markers in sources; epoch-milli math producing negatives far below int range.
Related errors
- Value %d exceeds MAX_INT
- position is not valid
- "Expected entry size to be exactly " + INT128_BYTES + " byte
- Current entry must be closed before a null can be written
- position is not valid
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/7ec96bc50bd22995.
Report an issue: GitHub.