apache/iceberg · error · UnsupportedOperationException
Unsupported base type for decimal: " + primitive.getPrimitiv
Error message
Unsupported base type for decimal: " + primitive.getPrimitiveTypeName()
What it means
This is the same 'Unsupported base type for decimal' error thrown from the non-dictionary branch of getVectorAccessor (line 157 vs 256 for the dictionary branch). A plain (non-dictionary-encoded) decimal column's Parquet base type is not one of the supported physical types, so accessor construction fails.
Source
Thrown at arrow/src/main/java/org/apache/iceberg/arrow/vectorized/GenericArrowVectorAccessorFactory.java:157
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 backwards
// compatibility we try to read INT96 as timestamps. But INT96 is not recommended
// and deprecated (see https://issues.apache.org/jira/browse/PARQUET-323)
return new DictionaryTimestampInt96Accessor<>((IntVector) vector, dictionary);
case DOUBLE:View on GitHub (pinned to 86d9c8fc54)
Solutions
- Validate the Parquet schema's physical type for decimal columns before vectorized reads
- Rewrite the files with standard writers (decimal over FIXED_LEN_BYTE_ARRAY/INT64/INT32)
- Use the generic Parquet row reader for these files instead of the Arrow path
Defensive patterns
Strategy: fallback
Validate before calling
if (decimalPhysicalTypes.stream().noneMatch(t -> t == primitive.getPrimitiveTypeName())) { skipVectorized(column); } Try / catch
try { accessor = factory.getVectorAccessor(holder); } catch (UnsupportedOperationException e) { if (e.getMessage().startsWith("Unsupported base type for decimal")) { accessor = null; } else throw e; } Prevention
- Run parquet-tools/schema inspection on external files before vectorized reads
- Normalize decimal storage (FIXED_LEN_BYTE_ARRAY/INT64/INT32) at write time
- Gate vectorized reads per file/column based on schema checks
When it happens
Trigger: getVectorAccessor resolving a plain decimal column whose PrimitiveTypeName is outside FIXED_LEN_BYTE_ARRAY/BINARY, INT64, INT32; passing a malformed or foreign Parquet schema to the Arrow accessor factory.
Common situations: External Parquet files (non-Iceberg writers) registered directly; corrupted or hand-edited Parquet metadata claiming decimal logical type over an unsupported physical type.
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 primitive type for decimal: <type>
- Unsupported base type for decimal:
- Buffer size of %d is larger than requested size of %d
- Cannot parse default as a %s value: %s
- Invalid primitive type for decimal:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/ccfe58188a7ac9f2.
Report an issue: GitHub.