apache/iceberg · error · IllegalArgumentException

Invalid precision:

Error message

Invalid precision: 

What it means

SparkOrcValueReaders.decimals creates ORC decimal readers by precision: up to MAX_LONG_DIGITS uses Decimal18Reader, up to 38 uses Decimal38Reader, and anything above 38 throws IllegalArgumentException('Invalid precision: ' + precision). Decimal precision beyond 38 is not representable in Iceberg/Spark.

Source

Thrown at spark/v4.0/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. Reduce the decimal precision to <= 38 in the source data or schema
  2. Cast/convert oversized decimals to strings or scaled longs before Iceberg reads them
  3. Fix the ORC schema if the precision is wrong (external writer misconfiguration)
  4. Verify Iceberg's supported decimal range (precision 1-38) when defining table schemas

Example fix

// before
TypeDescription schema = TypeDescription.createDecimal(42, 4);
// after
TypeDescription schema = TypeDescription.createDecimal(38, 4);
Defensive patterns

Strategy: validation

Validate before calling

int precision = orcType.getPrecision();
if (precision > 38) {
  throw new IllegalArgumentException("Decimal precision " + precision + " exceeds Iceberg max of 38");
}

Type guard

boolean validDecimal(int precision) { return precision >= 1 && precision <= 38; }

Try / catch

try { OrcValueReader<?> r = SparkOrcValueReaders.decimals(precision, scale); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Invalid precision")) { /* convert data */ } else { throw e; } }

Prevention

When it happens

Trigger: Registering/reading an ORC file whose schema declares a decimal with precision > 38, causing decimals(precision, scale) to reject it.

Common situations: ORC data written by external engines allowing wider decimals; schema conversion mapping ORC decimals with unsupported precision into an Iceberg read path; incorrect precision in hand-written schemas.

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/1dd32afbc93e2fcf. Report an issue: GitHub.