prestodb/presto · error · OrcCorruptionException

Decoded value out of range for a 32bit number

Error message

Decoded value out of range for a 32bit number

What it means

LongInputStreamV2.next(int[], items) buffers decoded RLEv2 literals as longs and narrows each to an int when filling the caller's int[] column. If a literal's value changes when narrowed to 32 bits, the stream's values cannot be represented as ints and Presto throws OrcCorruptionException rather than silently truncating.

Source

Thrown at presto-orc/src/main/java/com/facebook/presto/orc/stream/LongInputStreamV2.java:374

    @Override
    public void next(int[] values, int items)
            throws IOException
    {
        int offset = 0;
        while (items > 0) {
            if (used == numLiterals) {
                numLiterals = 0;
                used = 0;
                readValues();
            }

            int chunkSize = min(numLiterals - used, items);
            for (int i = 0; i < chunkSize; i++) {
                long literal = literals[used + i];
                int value = (int) literal;
                if (literal != value) {
                    throw new OrcCorruptionException(input.getOrcDataSourceId(), "Decoded value out of range for a 32bit number");
                }
                values[offset + i] = value;
            }
            used += chunkSize;
            offset += chunkSize;
            items -= chunkSize;
        }
    }

    @Override
    public void next(short[] values, int items)
            throws IOException
    {
        int offset = 0;
        while (items > 0) {
            if (used == numLiterals) {
                numLiterals = 0;
                used = 0;

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Check the ORC footer's declared column type; align the Presto table schema with it (use BIGINT if values exceed int range).
  2. Validate/re-copy the file; run orc-tools scan to locate the corrupt stripe.
  3. Re-write the file with a current ORC writer if the producer overflowed delta values.
  4. If widening the type is not possible, filter or coerce upstream (read as BIGINT then CAST).
  5. Upgrade Presto if a known decoding bug matches your writer version.

Example fix

// before
CREATE TABLE t (id INT) WITH (external_location = 's3://bucket/wide.orc'); -- fails

// after: widen the column to match actual data range
CREATE TABLE t (id BIGINT) WITH (external_location = 's3://bucket/wide.orc');
Defensive patterns

Strategy: validation

Validate before calling

// Check declared type vs value range before query:
// orc-tools meta data.orc  -> confirm column is INTEGER;
// orc-scan data.orc | awk '$1 < -2147483648 || $1 > 2147483647 {bad++} END {exit bad>0}'

Try / catch

try {
    session.execute("SELECT int_col FROM table");
} catch (PrestoException e) {
    if (e.getErrorCode().getCode() == OrcErrorCode.ORC_BAD_DATA.getCode()) {
        // retry with the column read as BIGINT
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Reading an INTEGER-typed ORC column whose RLEv2 literals exceed Integer.MIN_VALUE..Integer.MAX_VALUE — caused by corrupt data, an integer-overflowing DELTA run, or a writer that stored values wider than the declared column type.

Common situations: Files written by buggy writers (e.g. delta encoding overflowing), schema drift where a BIGINT column is read as INT, corrupted delta arithmetic in patched/delta streams, or tool version incompatibilities between writer and reader.

Related errors


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