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

  1. Widen the column type to INT (or BIGINT) so decoding uses the wider path that can represent the values.
  2. Validate the file with orc-tools; if bytes are corrupt, restore from backup or re-write the file.
  3. Align the reader's schema with the writer's actual column type to prevent misinterpreting stream width.
  4. 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

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


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