apache/iceberg · error · UnsupportedOperationException
Unsupported logical type: " + primitive.getOriginalType()
Error message
Unsupported logical type: " + primitive.getOriginalType()
What it means
The dictionary accessor switch is keyed on the Parquet original (logical) type; if a column's OriginalType is not one of the handled logical types (UTF8, decimal, timestamp variants, int96 timestamp, etc.), the default branch throws this UnsupportedOperationException. It means the logical type has no vectorized dictionary accessor mapping.
Source
Thrown at arrow/src/main/java/org/apache/iceberg/arrow/vectorized/GenericArrowVectorAccessorFactory.java:159
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:
return new DictionaryDoubleAccessor<>((IntVector) vector, dictionary);
default:View on GitHub (pinned to 86d9c8fc54)
Solutions
- Upgrade Iceberg/parquet-mr to a version mapping the column's logical type
- Drop the unsupported logical annotation by rewriting the column as its base physical type
- Read these columns through the non-vectorized path
Defensive patterns
Strategy: fallback
Validate before calling
if (!SUPPORTED_LOGICAL_TYPES.contains(primitive.getOriginalType())) { useRowReader(column); } Try / catch
try { accessor = factory.getVectorAccessor(holder); } catch (UnsupportedOperationException e) { if (e.getMessage().startsWith("Unsupported logical type")) { accessor = rowAccessor(holder); } else throw e; } Prevention
- Keep Iceberg and parquet-mr versions current to cover new Parquet logical types
- Audit external files for logical annotations beyond the supported set
- Restrict vectorized reads to columns with known-supported logical types
When it happens
Trigger: Reading a dictionary-encoded column whose Parquet logical type is unmapped (e.g. newer logical types like JSON, BSON, UUID, or unknown future types) through the vectorized read path.
Common situations: Files written with newer Parquet logical annotations than this Iceberg version supports; forward-compatibility gaps after Parquet spec additions without upgrading Iceberg.
Related errors
- Unsupported base type for decimal:
- Unsupported type: " + primitive
- 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/e75bba6bf1ee508d.
Report an issue: GitHub.