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.

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.

Appendix: 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)