{"record":{"id":"6aca12f58a314720","repo":"apache/iceberg","slug":"invalid-precision-precision-6aca12","errorCode":null,"errorMessage":"Invalid precision: {precision}","messagePattern":"Invalid precision: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/data/SparkOrcValueReaders.java","lineNumber":69,"sourceCode":"  public static OrcValueReader<UTF8String> utf8String() {\n    return StringReader.INSTANCE;\n  }\n\n  public static OrcValueReader<UTF8String> uuids() {\n    return UUIDReader.INSTANCE;\n  }\n\n  public static OrcValueReader<Long> timestampTzs() {\n    return TimestampTzReader.INSTANCE;\n  }\n\n  public static OrcValueReader<Decimal> decimals(int precision, int scale) {\n    if (precision <= Decimal.MAX_LONG_DIGITS()) {\n      return new SparkOrcValueReaders.Decimal18Reader(precision, scale);\n    } else if (precision <= 38) {\n      return new SparkOrcValueReaders.Decimal38Reader(precision, scale);\n    } else {\n      throw new IllegalArgumentException(\"Invalid precision: \" + precision);\n    }\n  }\n\n  static OrcValueReader<?> struct(\n      TypeDescription record,\n      List<OrcValueReader<?>> readers,\n      Types.StructType struct,\n      Map<Integer, ?> idToConstant) {\n    return new StructReader(record, readers, struct, idToConstant);\n  }\n\n  static OrcValueReader<?> array(OrcValueReader<?> elementReader) {\n    return new ArrayReader(elementReader);\n  }\n\n  static OrcValueReader<?> map(OrcValueReader<?> keyReader, OrcValueReader<?> valueReader) {\n    return new MapReader(keyReader, valueReader);\n  }","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/data/SparkOrcValueReaders.java#L51-L87","documentation":"SparkOrcValueReaders.decimals(precision, scale) selects a Decimal18Reader or Decimal38Reader based on precision. Iceberg decimals are limited to precision <= 38; anything greater cannot be represented, so the factory throws IllegalArgumentException immediately rather than producing a corrupt reader.","triggerScenarios":"Constructing an ORC reader/writer mapping for a decimal column whose precision exceeds 38, usually from a schema that violates the Iceberg spec (max precision 38).","commonSituations":"Tables created by non-Iceberg tools with oversized decimals; schema conversion bugs; spec-violating metadata injected into ORC files.","solutions":["Fix the schema so decimal precision is <= 38 per the Iceberg spec","Reduce precision (e.g. DECIMAL(38,x)) and rewrite the data","Validate table schemas with Schema validation before writing ORC files","Check the producing system for precision-scaling bugs"],"exampleFix":"// before\nTypes.DecimalType.of(40, 5)\n// after\nTypes.DecimalType.of(38, 5)","handlingStrategy":"validation","validationCode":"Types.DecimalType t = (Types.DecimalType) type;\nif (t.precision() > 38) {\n  throw new IllegalArgumentException(\"Decimal precision exceeds Iceberg max (38): \" + t.precision());\n}","typeGuard":"boolean isValidDecimal(Type t) {\n  return t instanceof Types.DecimalType && ((Types.DecimalType) t).precision() <= 38;\n}","tryCatchPattern":"try {\n  OrcValueReader<?> r = SparkOrcValueReaders.decimals(precision, scale);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Invalid precision\")) { /* fix schema precision */ }\n  else throw e;\n}","preventionTips":["Enforce decimal precision <= 38 at schema creation time","Validate external schemas before registering tables","Add schema conformance checks in ingestion pipelines"],"tags":["spark","orc","decimal","validation"],"backgroundTag":"value-out-of-range","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}