apache/iceberg · error · UnsupportedOperationException
Unsupported decimal precision:
Error message
Unsupported decimal precision:
What it means
Variants.of(BigDecimal) maps a decimal to a PhysicalType based on precision: DECIMAL4 (<=9), DECIMAL8 (10-18), DECIMAL16 (<=38). The variant spec caps decimal precision at 38, so any precision above 38 throws UnsupportedOperationException because no variant physical encoding exists for it.
Solutions
- Reduce the BigDecimal precision to <=38 via value.setScale(..., roundingMode) or value.round(mathContext)
- Check precision before conversion and reject/alter oversized decimals
- Use a non-variant storage path for decimals with precision > 38
Example fix
// before VariantPrimitive<BigDecimal> v = Variants.of(bigValue); // after BigDecimal capped = bigValue.round(new MathContext(38)); VariantPrimitive<BigDecimal> v = Variants.of(capped);
Defensive patterns
Strategy: validation
Validate before calling
if (value.precision() > 38) { throw new IllegalArgumentException("Decimal precision " + value.precision() + " exceeds variant max 38"); } Type guard
boolean isVariantCompatible(BigDecimal v) { return v.precision() <= 38; } Try / catch
try { return Variants.of(value); } catch (UnsupportedOperationException e) { return null; /* or serialize as string */ } Prevention
- Set explicit scale/precision MathContext on computed BigDecimals
- Validate decimal precision at schema boundaries (columns are max decimal(38))
- Avoid raw BigDecimal division without rounding context
When it happens
Trigger: Calling Variants.of(BigDecimal) with a BigDecimal whose precision() > 38, e.g. new BigDecimal("12345678901234567890123456789012345678901234567890") or computed division results with huge precision.
Common situations: High-precision financial computations or BigDecimal division producing expanded precision beyond 38 digits; schema columns declared decimal(39+) being converted to variants.
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/2e3b705f83b977fa.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/variants/Variants.java:202
return new PrimitiveWrapper<>(PhysicalType.TIMESTAMPNTZ, value);
}
public static VariantPrimitive<Long> ofIsoTimestampntz(String value) {
return ofTimestampntz(DateTimeUtil.isoTimestampToMicros(value));
}
public static VariantPrimitive<BigDecimal> of(BigDecimal value) {
int precision = value.precision();
if (precision >= 1 && precision <= 9) {
return new PrimitiveWrapper<>(PhysicalType.DECIMAL4, value);
} else if (precision >= 10 && precision <= 18) {
return new PrimitiveWrapper<>(PhysicalType.DECIMAL8, value);
} else if (precision <= 38) {
return new PrimitiveWrapper<>(PhysicalType.DECIMAL16, value);
}
throw new UnsupportedOperationException("Unsupported decimal precision: " + precision);
}
public static VariantPrimitive<ByteBuffer> of(ByteBuffer value) {
return new PrimitiveWrapper<>(PhysicalType.BINARY, value);
}
public static VariantPrimitive<String> of(String value) {
return new PrimitiveWrapper<>(PhysicalType.STRING, value);
}
public static VariantPrimitive<Long> ofTime(long value) {
return new PrimitiveWrapper<>(PhysicalType.TIME, value);
}
public static VariantPrimitive<Long> ofIsoTime(String value) {
return ofTime(DateTimeUtil.isoTimeToMicros(value));
}
View on GitHub (pinned to 86d9c8fc54)