apache/iceberg · error · IllegalArgumentException

Invalid precision:

Error message

Invalid precision: 

What it means

SparkOrcValueReaders.decimals picks a Decimal18Reader (precision <= 18) or Decimal38Reader (precision <= 38) based on the decimal precision. Any precision above 38 is invalid for Iceberg/ORC decimals. This IllegalArgumentException reports a decimal precision that exceeds the 38-digit maximum.

Source

Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/data/SparkOrcValueReaders.java:69

  public static OrcValueReader<UTF8String> utf8String() {
    return StringReader.INSTANCE;
  }

  public static OrcValueReader<UTF8String> uuids() {
    return UUIDReader.INSTANCE;
  }

  public static OrcValueReader<Long> timestampTzs() {
    return TimestampTzReader.INSTANCE;
  }

  public static OrcValueReader<Decimal> decimals(int precision, int scale) {
    if (precision <= Decimal.MAX_LONG_DIGITS()) {
      return new SparkOrcValueReaders.Decimal18Reader(precision, scale);
    } else if (precision <= 38) {
      return new SparkOrcValueReaders.Decimal38Reader(precision, scale);
    } else {
      throw new IllegalArgumentException("Invalid precision: " + precision);
    }
  }

  static OrcValueReader<?> struct(
      TypeDescription record,
      List<OrcValueReader<?>> readers,
      Types.StructType struct,
      Map<Integer, ?> idToConstant) {
    return new StructReader(record, readers, struct, idToConstant);
  }

  static OrcValueReader<?> array(OrcValueReader<?> elementReader) {
    return new ArrayReader(elementReader);
  }

  static OrcValueReader<?> map(OrcValueReader<?> keyReader, OrcValueReader<?> valueReader) {
    return new MapReader(keyReader, valueReader);
  }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Change the column to decimal(38, scale) or smaller precision.
  2. Rewrite the external data with precision <= 38 before reading via Iceberg.
  3. Cast/widen handling at the source engine before the data reaches Iceberg's reader.

Example fix

// before
ALTER TABLE t ADD COLUMN d DECIMAL(50,10)
// after
ALTER TABLE t ADD COLUMN d DECIMAL(38,10)
Defensive patterns

Strategy: validation

Validate before calling

int precision = ((org.apache.iceberg.types.Types.DecimalType) type).precision();
if (precision > 38) {
  throw new IllegalArgumentException("decimal precision must be <= 38, got " + precision);
}

Type guard

static boolean isValidDecimal(org.apache.iceberg.types.Type t) {
  if (t instanceof org.apache.iceberg.types.Types.DecimalType d) {
    return d.precision() >= 1 && d.precision() <= 38 && d.scale() >= 0 && d.scale() <= d.precision();
  }
  return false;
}

Prevention

When it happens

Trigger: Reading ORC data whose schema declares a decimal with precision > 38, e.g. DECIMAL(50,10), during a Spark read through Iceberg.

Common situations: Tables created or written by systems that allow wider decimals than Iceberg's 38-digit limit; schema drift after importing external ORC data.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/00b640a36c162846. Report an issue: GitHub.