prestodb/presto · error · OrcCorruptionException
Decoded value out of range for a 16bit number
Error message
Decoded value out of range for a 16bit number
What it means
next(short[], items) decodes values as longs (run-mode reconstruction or varint literals) and narrows them to short (16-bit). When a decoded long does not fit in a short, the data contradicts the column's SMALLINT declaration. The library throws OrcCorruptionException instead of returning a value mangled by 16-bit truncation.
Source
Thrown at presto-orc/src/main/java/com/facebook/presto/orc/stream/LongInputStreamV1.java:176
@Override
public void next(short[] values, int items)
throws IOException
{
int offset = 0;
while (items > 0) {
if (used == numValuesInRun) {
numValuesInRun = 0;
used = 0;
readHeader();
}
int chunkSize = min(numValuesInRun - used, items);
if (repeat) {
for (int i = 0; i < chunkSize; i++) {
long literal = repeatBase + ((used + i) * delta);
short value = (short) literal;
if (literal != value) {
throw new OrcCorruptionException(input.getOrcDataSourceId(), "Decoded value out of range for a 16bit number");
}
values[offset + i] = value;
}
}
else {
for (int i = 0; i < chunkSize; i++) {
long literal = input.readVarint(signed);
short value = (short) literal;
if (literal != value) {
throw new OrcCorruptionException(input.getOrcDataSourceId(), "Decoded value out of range for a 16bit number");
}
values[offset + i] = value;
}
}
used += chunkSize;
offset += chunkSize;
items -= chunkSize;
}View on GitHub (pinned to 55bb57d202)
Solutions
- Widen the column type to INT (or BIGINT) so decoding uses the wider path that can represent the values.
- Validate the file with orc-tools; if bytes are corrupt, restore from backup or re-write the file.
- Align the reader's schema with the writer's actual column type to prevent misinterpreting stream width.
- Fix the producer if it emits out-of-range values for declared SMALLINT columns.
Example fix
// before CREATE TABLE t (v SMALLINT) STORED AS ORC; // values exceed 16 bits // after ALTER TABLE t CHANGE v v INT;
Defensive patterns
Strategy: validation
Validate before calling
long minValue = sampleMinValue(orcFile, "my_smallint_col");
long maxValue = sampleMaxValue(orcFile, "my_smallint_col");
if (minValue < Short.MIN_VALUE || maxValue > Short.MAX_VALUE) {
throw new SchemaMismatchException("values exceed SMALLINT range; use INT/BIGINT column");
} Type guard
static boolean fitsShort(long v) { return v >= Short.MIN_VALUE && v <= Short.MAX_VALUE; } Try / catch
try {
return shortStream.next(values, items);
} catch (OrcCorruptionException e) {
if (e.getMessage().contains("out of range for a 16bit number")) {
LOG.error("SMALLINT column holds values outside 16-bit range; re-read as INT");
return intReader.next(); // re-decode via the 32-bit path
}
throw e;
} Prevention
- Choose SMALLINT only when domain values are provably within -32768..32767.
- Widen columns (SMALLINT → INT) proactively when producers may emit larger values.
- Validate ORC files with orc-tools before registering them in the metastore.
- Keep writer-side range checks in place so out-of-range values never reach encoded streams.
When it happens
Trigger: next() called on a 16-bit column stream where repeatBase + (used + i) * delta (run mode) or a varint literal exceeds short range (-32768..32767) — corrupt bytes or the column actually holds INT/BIGINT-width data.
Common situations: SMALLINT columns whose writers encoded values beyond 16 bits, schema drift (column widened from SMALLINT to INT upstream), or corrupted ORC files after storage faults.
Related errors
- Decoded value out of range for a 32bit number
- Can not read SQL type %s from ORC stream %s of type %s
- HIVE_CURSOR_ERROR
- File has no columns
- Stripe encryption keys are missing, but file is encrypted
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/6f53191343349bc5.
Report an issue: GitHub.