apache/iceberg · error · UnsupportedOperationException
Unsupported base type for decimal: ${primitive.getPrimitiveT
Error message
Unsupported base type for decimal: ${primitive.getPrimitiveTypeName()} What it means
When reading Parquet, decimal columns can be physically stored as FIXED_LEN_BYTE_ARRAY, BINARY, INT64, or INT32. SparkParquetReaders' primitive() method throws UnsupportedOperationException if a DECIMAL-annotated column uses any other base physical type, since no decimal reader exists for it.
Source
Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/data/SparkParquetReaders.java:271
case DATE:
case INT_64:
return new UnboxedReader<>(desc);
case TIMESTAMP_MICROS:
case TIMESTAMP_MILLIS:
return ParquetValueReaders.timestamps(desc);
case DECIMAL:
DecimalLogicalTypeAnnotation decimal =
(DecimalLogicalTypeAnnotation) primitive.getLogicalTypeAnnotation();
switch (primitive.getPrimitiveTypeName()) {
case BINARY:
case FIXED_LEN_BYTE_ARRAY:
return new BinaryDecimalReader(desc, decimal.getScale());
case INT64:
return new LongDecimalReader(desc, decimal.getPrecision(), decimal.getScale());
case INT32:
return new IntegerDecimalReader(desc, decimal.getPrecision(), decimal.getScale());
default:
throw new UnsupportedOperationException(
"Unsupported base type for decimal: " + primitive.getPrimitiveTypeName());
}
case BSON:
return new ParquetValueReaders.ByteArrayReader(desc);
default:
throw new UnsupportedOperationException(
"Unsupported logical type: " + primitive.getOriginalType());
}
}
switch (primitive.getPrimitiveTypeName()) {
case FIXED_LEN_BYTE_ARRAY:
case BINARY:
if (expected != null && expected.typeId() == TypeID.UUID) {
return new UUIDReader(desc);
}
return new ParquetValueReaders.ByteArrayReader(desc);
case INT32:View on GitHub (pinned to 86d9c8fc54)
Solutions
- Rewrite the offending files with a standards-compliant writer (e.g. rewrite_data_files procedure).
- Check the Parquet footer to confirm the decimal column's physical type.
- Exclude or repair files written by the non-conforming producer before reading.
Defensive patterns
Strategy: validation
Validate before calling
ParquetMetadata meta = ParquetFileReader.readFooter(conf, path);
for (ColumnDescriptor cd : meta.getFileMetaData().getSchema().getColumns()) {
OriginalType ot = cd.getPrimitiveType().getOriginalType();
if (ot == OriginalType.DECIMAL) {
Primitive p = cd.getPrimitiveType().getPrimitiveTypeName();
if (p != FIXED_LEN_BYTE_ARRAY && p != BINARY && p != INT64 && p != INT32)
throw new IllegalStateException("bad decimal base: " + cd.getPath());
}
} Try / catch
try {
icebergTable.newScan().toSpark().load();
} catch (UnsupportedOperationException e) {
if (e.getMessage().startsWith("Unsupported base type for decimal")) {
// rewrite offending files via rewrite_data_files
}
} Prevention
- Write Parquet decimals only via conforming writers.
- Validate external Parquet files before registering them with Iceberg (add_files checks).
When it happens
Trigger: Reading a Parquet file whose decimal column is stored on an unexpected physical type (e.g. FLOAT/DOUBLE or INT96 with DECIMAL logical type) — typically from files written by non-conforming tools.
Common situations: Parquet files produced by legacy or buggy writers storing decimals with unusual physical representations; corrupted schema metadata; mixing files from different writers in one table.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Unsupported base type for decimal:
- Unsupported base type for decimal:
- Unsupported base type for decimal: ${primitive.getPrimitiveT
- Unsupported type: ${primitive}
- Unsupported logical type:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/ee64d9c4b3a4bdd7.
Report an issue: GitHub.