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

  1. Check the Parquet column's LogicalTypeAnnotation and rewrite/re-encode the file with MILLIS, MICROS or NANOS
  2. Upgrade Iceberg to a version whose ParquetValueReaders handles the unit used by the file
  3. 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

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


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)