apache/iceberg · error · UnsupportedOperationException
UnsupportedOperationException with no message (TimestampInt9
Error message
UnsupportedOperationException with no message (TimestampInt96Reader.nextDictEncodedVal)
What it means
TimestampInt96Reader.nextDictEncodedVal is implemented to always throw an UnsupportedOperationException with no message — INT96 timestamps are simply not supported in dictionary-encoded vectorized decoding. Unlike error 292 (which has a message for unknown modes), this is an unconditional refusal.
Source
Thrown at arrow/src/main/java/org/apache/iceberg/arrow/vectorized/parquet/VectorizedParquetDefinitionLevelReader.java:652
FieldVector vector,
int idx,
VectorizedValuesReader valuesReader,
int typeWidth,
byte[] byteArray) {
((BitVector) vector).setSafe(idx, valuesReader.readBoolean() ? 1 : 0);
}
@Override
protected void nextDictEncodedVal(
FieldVector vector,
int idx,
VectorizedDictionaryEncodedParquetValuesReader reader,
Dictionary dict,
Mode mode,
int numValues,
NullabilityHolder holder,
int typeWidth) {
throw new UnsupportedOperationException();
}
}
class DictionaryIdReader extends BaseReader {
@Override
protected void nextVal(
FieldVector vector,
int idx,
VectorizedValuesReader valuesReader,
int typeWidth,
byte[] byteArray) {
throw new UnsupportedOperationException();
}
@Override
protected void nextDictEncodedVal(
FieldVector vector,View on GitHub (pinned to 86d9c8fc54)
Solutions
- Disable vectorized reads (read.parquet.vectorization.enabled=false) to fall back to the generic reader.
- Rewrite/compact the table converting INT96 timestamps to INT64 with a timestamp logical type.
- Implement nextDictEncodedVal for INT96 if dictionary-encoded INT96 support is needed.
Example fix
// before
spark.read.format("iceberg").load("db.table") // fails on dict-encoded INT96
// after
table.newScan().option("read.parquet.vectorization.enabled", "false"); Defensive patterns
Strategy: fallback
Validate before calling
boolean isInt96 = desc.getPrimitiveType().getPrimitiveTypeName() == PrimitiveTypeName.INT96;
boolean dictEncoded = pageEncoding != null && pageEncoding.isDictionaryEncoded();
if (isInt96 && dictEncoded) { vectorizationSupported = false; } Try / catch
try {
return readVectorizedBatch();
} catch (UnsupportedOperationException e) {
return readRowOrientedBatch(); // non-vectorized path supports INT96
} Prevention
- Rewrite tables to INT64 timestamp logical types — INT96 is deprecated in the Parquet spec.
- Set read.parquet.vectorization.enabled=false on legacy Hive/Impala tables.
- Check column encodings in the footer before choosing the vectorized path.
When it happens
Trigger: Any call to nextDictEncodedVal on a TimestampInt96Reader, i.e. vectorized reading of a dictionary-encoded INT96 timestamp column that takes the dictionary decode path (e.g. packed dictionary decoding).
Common situations: Legacy Parquet files (Hive/Impala/old Spark) storing timestamps as INT96 with dictionary-encoded pages read through the Iceberg vectorized Arrow reader; the vectorized INT96 reader only supports plain (non-dictionary) reads.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Unsupported mode for timestamp int96 reader: " + mode
- Unsupported base type for decimal:
- Unsupported logical type: " + primitive.getOriginalType()
- Unsupported type: " + primitive
- 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/1e269dd9d19d7d18.
Report an issue: GitHub.