apache/iceberg · error · UnsupportedOperationException
Unsupported base type for decimal:
Error message
Unsupported base type for decimal:
What it means
When a column is dictionary-encoded, the factory builds a Dictionary*Accessor whose backing type must match the decimal's Parquet base type (FIXED_LEN_BYTE_ARRAY, INT64, or INT32). A decimal stored with any other base physical type has no dictionary accessor implementation, so the default branch throws this error.
Source
Thrown at arrow/src/main/java/org/apache/iceberg/arrow/vectorized/GenericArrowVectorAccessorFactory.java:153
case INT_64:
case TIME_MICROS:
case TIMESTAMP_MILLIS:
case TIMESTAMP_MICROS:
return new DictionaryLongAccessor<>((IntVector) vector, dictionary);
case DECIMAL:
switch (primitive.getPrimitiveTypeName()) {
case BINARY:
case FIXED_LEN_BYTE_ARRAY:
return new DictionaryDecimalBinaryAccessor<>(
(IntVector) vector, dictionary, decimalFactorySupplier.get());
case INT64:
return new DictionaryDecimalLongAccessor<>(
(IntVector) vector, dictionary, decimalFactorySupplier.get());
case INT32:
return new DictionaryDecimalIntAccessor<>(
(IntVector) vector, dictionary, decimalFactorySupplier.get());
default:
throw new UnsupportedOperationException(
"Unsupported base type for decimal: " + primitive.getPrimitiveTypeName());
}
default:
throw new UnsupportedOperationException(
"Unsupported logical type: " + primitive.getOriginalType());
}
} else {
switch (primitive.getPrimitiveTypeName()) {
case FIXED_LEN_BYTE_ARRAY:
case BINARY:
return new DictionaryBinaryAccessor<>(
(IntVector) vector, dictionary, stringFactorySupplier.get());
case FLOAT:
return new DictionaryFloatAccessor<>((IntVector) vector, dictionary);
case INT64:
return new DictionaryLongAccessor<>((IntVector) vector, dictionary);
case INT96:
// Impala & Spark used to write timestamps as INT96 by default. For backwardsView on GitHub (pinned to 86d9c8fc54)
Solutions
- Rewrite/compact the data with standard Iceberg writers so decimals use the canonical physical types
- Fall back to the non-vectorized (row) reader for such files
- Inspect the Parquet schema (parquet-tools) to confirm the decimal's physical type and fix at write time
Defensive patterns
Strategy: fallback
Validate before calling
LogicalTypeAnnotation ann = primitive.getLogicalTypeAnnotation(); if (ann instanceof DecimalLogicalTypeAnnotation && !EnumSet.of(FIXED_LEN_BYTE_ARRAY, INT64, INT32).contains(primitive.getPrimitiveTypeName())) { useRowReader(); } Try / catch
try { accessor = factory.getVectorAccessor(holder); } catch (UnsupportedOperationException e) { accessor = rowBasedAccessor(holder); } Prevention
- Validate Parquet schemas on ingestion so decimals use canonical physical types
- Prefer Iceberg writers for all files consumed by vectorized reads
- Keep a non-vectorized fallback path in the read pipeline
When it happens
Trigger: Reading a dictionary-encoded Parquet decimal column whose primitive base type is not FIXED_LEN_BYTE_ARRAY/INT64/INT32 (e.g. an unexpected physical encoding produced by a non-standard writer), via getVectorAccessor on a VectorHolder with a dictionary.
Common situations: Files written by third-party/older Parquet writers using unusual physical types for decimal logical type; mixed-writer datasets where encoding metadata doesn't match Iceberg's expectations.
Related errors
- Unsupported base type for decimal: " + primitive.getPrimitiv
- Unsupported logical type: " + primitive.getOriginalType()
- Unsupported type: " + primitive
- Buffer size of %d is larger than requested size of %d
- could not read page in col " + desc + " as the dictionary wa
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/8dd803f79b1d10e3.
Report an issue: GitHub.