apache/iceberg · error · IllegalArgumentException
Unsupported timestamp unit
Error message
Unsupported timestamp unit: <unit>
What it means
This error is thrown by ParquetValueReaders.timestamps() when a TIMESTAMP logical type annotation has a unit that the reader does not support. Only MILLIS, MICROS and NANOS are mapped to concrete readers; anything else (or an unexpected unit enumeration) falls through to this IllegalArgumentException. It indicates the Parquet file's timestamp unit cannot be mapped to an Iceberg reader.
Solutions
- Check the Parquet column's LogicalTypeAnnotation and rewrite/re-encode the file with MILLIS, MICROS or NANOS
- Upgrade Iceberg to a version whose ParquetValueReaders handles the unit used by the file
- Intercept the schema during read planning and cast/repartition the timestamp column before it reaches the reader
Example fix
// before: file written with a nonstandard timestamp unit
Types.NestedField.field("ts", Types.TimestampType.withoutZone()) // backed by unsupported unit
// after: rewrite the file with a supported unit (e.g. MICROS)
new ParquetAvroValueWriters.TimestampMicrosWriter(column);
// or upgrade iceberg-parquet to a version that maps the unit Defensive patterns
Strategy: validation
Validate before calling
LogicalTypeAnnotation la = desc.getPrimitiveType().getLogicalTypeAnnotation();
if (la instanceof TimestampLogicalTypeAnnotation) {
TimestampLogicalTypeAnnotation ts = (TimestampLogicalTypeAnnotation) la;
if (ts.getUnit() != TimeUnit.MILLIS && ts.getUnit() != TimeUnit.MICROS && ts.getUnit() != TimeUnit.NANOS) {
throw new IllegalArgumentException("Timestamp unit not supported: " + ts.getUnit());
}
} Type guard
boolean isSupportedTimestampUnit(LogicalTypeAnnotation la) {
return la instanceof TimestampLogicalTypeAnnotation
&& EnumSet.of(TimeUnit.MILLIS, TimeUnit.MICROS, TimeUnit.NANOS)
.contains(((TimestampLogicalTypeAnnotation) la).getUnit());
} Prevention
- Write Parquet files with MILLIS/MICROS/NANOS timestamp units only
- Pin parquet-mr and Iceberg versions together; re-read files after library upgrades in a staging job
- Validate file schemas against the expected Iceberg schema before reading
When it happens
Trigger: Calling ParquetValueReaders.timestamps(container, desc, convertConstant) on a column whose LogicalTypeAnnotation is a TimestampLogicalTypeAnnotation whose TimeUnit is not MILLIS, MICROS or NANOS (e.g. a hand-built schema or a new unit added in a newer parquet-mr version).
Common situations: Reading Parquet files produced by other writers with unusual timestamp units; a parquet-mr library upgrade introducing a new TimeUnit constant that this Iceberg version does not handle; programmatic construction of Parquet schemas with invalid timestamp annotations.
Related errors
- Invalid unit for shredded timestamp
- Unsupported mode for timestamp int96 reader: " + mode
- Unsupported timestamp type:
- Unsupported timestamp type:
- Unsupported timestamp type
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/487706102694d23a.
Report an issue: GitHub.
Appendix: source
Thrown at parquet/src/main/java/org/apache/iceberg/parquet/ParquetValueReaders.java:155
if (desc.getPrimitiveType().getPrimitiveTypeName() == PrimitiveType.PrimitiveTypeName.INT96) {
return new TimestampInt96Reader(desc);
}
LogicalTypeAnnotation timestamp = desc.getPrimitiveType().getLogicalTypeAnnotation();
Preconditions.checkArgument(
timestamp instanceof TimestampLogicalTypeAnnotation,
"Invalid timestamp logical type: " + timestamp);
TimeUnit unit = ((TimestampLogicalTypeAnnotation) timestamp).getUnit();
switch (unit) {
case MILLIS:
return new TimestampMillisReader(desc);
case MICROS:
case NANOS:
return new UnboxedReader<>(desc);
}
throw new IllegalArgumentException("Unsupported timestamp unit: " + unit);
}
@SuppressWarnings("unchecked")
public static <T> ParquetValueReader<T> nulls() {
return (ParquetValueReader<T>) NullReader.INSTANCE;
}
public static <C> ParquetValueReader<C> constant(C value) {
return new ConstantReader<>(value);
}
public static <C> ParquetValueReader<C> constant(C value, int definitionLevel) {
return new ConstantReader<>(value, definitionLevel);
}
public static ParquetValueReader<Long> position() {
return new PositionReader();
}View on GitHub (pinned to 86d9c8fc54)