apache/iceberg · error · UnsupportedOperationException

Unsupported unit for timestamp

Error message

Unsupported unit for timestamp: %s

What it means

GenericParquetWriter.fromParquet maps a Parquet timestamp unit to a ChronoUnit for writer construction; only MICROS and NANOS map. Other units (e.g. MILLIS) throw UnsupportedOperationException since the writer has no conversion for them.

Solutions

  1. Write timestamps in MICROS (Iceberg's canonical representation) — adjust the requested Parquet schema.
  2. Convert the source values to micros/nanos before writing.
  3. Use a writer path that supports the unit you need.

Example fix

// before: requesting millis timestamp write
// Types.TimestampType -> parquet TIMESTAMP(MILLIS) -> throws
// after: use micros
Types.TimestampType.withZone(); // writes TIMESTAMP(MICROS)
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the target parquet timestamp unit is MICROS or NANOS before writing
if (targetUnit != TimeUnit.MICROSECONDS && targetUnit != TimeUnit.NANOSECONDS) {
  throw new IllegalArgumentException("Write timestamps as MICROS (or NANOS), not " + targetUnit);
}

Prevention

When it happens

Trigger: Writing a Parquet TIMESTAMP logical type with unit MILLIS (or anything other than MICROS/NANOS) through GenericParquetWriter.timestampWriter -> fromParquet.

Common situations: Interoperating with external files/writers that define MILLIS timestamp logical types and using the generic writer to produce matching schemas; hand-built Parquet schemas with unusual units.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/e8f0fd0063729431. Report an issue: GitHub.

Appendix: source

Thrown at parquet/src/main/java/org/apache/iceberg/data/parquet/GenericParquetWriter.java:168

    @Override
    public void write(int repetitionLevel, byte[] value) {
      Preconditions.checkArgument(
          value.length == length,
          "Cannot write byte buffer of length %s as fixed[%s]",
          value.length,
          length);
      column.writeBinary(repetitionLevel, Binary.fromReusedByteArray(value));
    }
  }

  private static ChronoUnit fromParquet(LogicalTypeAnnotation.TimeUnit unit) {
    switch (unit) {
      case MICROS:
        return ChronoUnit.MICROS;
      case NANOS:
        return ChronoUnit.NANOS;
      default:
        throw new UnsupportedOperationException("Unsupported unit for timestamp: " + unit);
    }
  }
}

View on GitHub (pinned to 86d9c8fc54)