apache/iceberg · error · UnsupportedOperationException
Unsupported type: " + primitive
Error message
Unsupported type: " + primitive
What it means
After the logical-type dispatch, the dictionary accessor path also switches on the raw PrimitiveTypeName (physical type); any physical type not handled (e.g. BOOLEAN, FLOAT, INT96-unmapped, or exotic types) hits the default branch and throws 'Unsupported type: ' + primitive. The vectorized dictionary reader supports only a fixed set of physical types.
Source
Thrown at arrow/src/main/java/org/apache/iceberg/arrow/vectorized/GenericArrowVectorAccessorFactory.java:178
} 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:
return new DictionaryDoubleAccessor<>((IntVector) vector, dictionary);
default:
throw new UnsupportedOperationException("Unsupported type: " + primitive);
}
}
}
@SuppressWarnings("checkstyle:CyclomaticComplexity")
private ArrowVectorAccessor<DecimalT, Utf8StringT, ArrayT, ChildVectorT> getPlainVectorAccessor(
FieldVector vector, PrimitiveType primitive) {
if (vector instanceof BitVector) {
return new BooleanAccessor<>((BitVector) vector);
} else if (vector instanceof IntVector) {
if (isDecimal(primitive)) {
return new IntBackedDecimalAccessor<>((IntVector) vector, decimalFactorySupplier.get());
}
return new IntAccessor<>((IntVector) vector);
} else if (vector instanceof BigIntVector) {
if (isDecimal(primitive)) {
return new LongBackedDecimalAccessor<>((BigIntVector) vector, decimalFactorySupplier.get());
}View on GitHub (pinned to 86d9c8fc54)
Solutions
- Check the column's physical type and exclude it from vectorized reads (use the row reader)
- Rewrite data with supported physical types (INT32/INT64/BINARY/FIXED_LEN_BYTE_ARRAY/DOUBLE/FLBA timestamps)
- Upgrade Iceberg if a newer version added an accessor for the type
Defensive patterns
Strategy: fallback
Validate before calling
if (!SUPPORTED_PHYSICAL_TYPES.contains(primitive.getPrimitiveTypeName())) { useRowReader(column); } Try / catch
try { accessor = factory.getVectorAccessor(holder); } catch (UnsupportedOperationException e) { if (e.getMessage().startsWith("Unsupported type:")) { accessor = rowAccessor(holder); } else throw e; } Prevention
- Enumerate the supported physical types in reader config and check columns against it
- Rewrite unsupported columns into supported physical encodings
- Always provide a row-based fallback for full type coverage
When it happens
Trigger: Requesting a vectorized accessor for a dictionary-encoded column whose physical Parquet type (e.g. FLOAT, BOOLEAN, INTERVAL) has no Dictionary*Accessor implementation.
Common situations: Third-party Parquet files with physical types Iceberg's vectorized reader never supported; expecting full type coverage in vectorized reads when it is limited to a known subset.
Related errors
- Unsupported base type for decimal:
- Unsupported logical type: " + primitive.getOriginalType()
- could not read page in col " + desc + " as the dictionary wa
- could not read page in col " + desc
- Unsupported mode for timestamp int96 reader: " + mode
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/78c1983911721363.
Report an issue: GitHub.