apache/iceberg · error · IllegalArgumentException

Invalid precision: ${precision}

Error message

Invalid precision: ${precision}

What it means

SparkOrcValueReaders.decimals selects a decimal reader based on precision: Decimal18Reader for precision <= MAX_LONG_DIGITS (18), Decimal38Reader for precision <= 38, otherwise IllegalArgumentException. It enforces the 38-digit maximum of the Iceberg/decimal spec.

Source

Thrown at spark/v4.2/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. Rescale the column to precision <= 38 before reading/writing with Iceberg.
  2. Fix the schema to use a valid precision (e.g. decimal(38, scale) maximum).
  3. If the data truly needs >38 digits, store it as string/binary instead of decimal.

Example fix

// before
column decimal(40, 5)  // throws
// after
column decimal(38, 5)
Defensive patterns

Strategy: validation

Validate before calling

if (precision > 38) throw new IllegalArgumentException("precision must be <= 38");

Type guard

boolean validDecimal(int precision, int scale) { return precision > 0 && precision <= 38 && scale >= 0 && scale <= precision; }

Try / catch

try { read } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Invalid precision")) { /* rescale column to <=38 */ } else throw e; }

Prevention

When it happens

Trigger: Reading ORC decimal columns whose declared precision exceeds 38, typically from schemas created outside Iceberg's constraints.

Common situations: ORC files with precision >38 decimals written by other engines; schema misconfiguration assigning oversized precision during table creation.

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/052bea07839a956e. Report an issue: GitHub.