{"record":{"id":"487706102694d23a","repo":"apache/iceberg","slug":"unsupported-timestamp-unit-unit","errorCode":null,"errorMessage":"Unsupported timestamp unit: <unit>","messagePattern":"Unsupported timestamp unit: <unit>","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"parquet/src/main/java/org/apache/iceberg/parquet/ParquetValueReaders.java","lineNumber":155,"sourceCode":"    if (desc.getPrimitiveType().getPrimitiveTypeName() == PrimitiveType.PrimitiveTypeName.INT96) {\n      return new TimestampInt96Reader(desc);\n    }\n\n    LogicalTypeAnnotation timestamp = desc.getPrimitiveType().getLogicalTypeAnnotation();\n    Preconditions.checkArgument(\n        timestamp instanceof TimestampLogicalTypeAnnotation,\n        \"Invalid timestamp logical type: \" + timestamp);\n\n    TimeUnit unit = ((TimestampLogicalTypeAnnotation) timestamp).getUnit();\n    switch (unit) {\n      case MILLIS:\n        return new TimestampMillisReader(desc);\n      case MICROS:\n      case NANOS:\n        return new UnboxedReader<>(desc);\n    }\n\n    throw new IllegalArgumentException(\"Unsupported timestamp unit: \" + unit);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> ParquetValueReader<T> nulls() {\n    return (ParquetValueReader<T>) NullReader.INSTANCE;\n  }\n\n  public static <C> ParquetValueReader<C> constant(C value) {\n    return new ConstantReader<>(value);\n  }\n\n  public static <C> ParquetValueReader<C> constant(C value, int definitionLevel) {\n    return new ConstantReader<>(value, definitionLevel);\n  }\n\n  public static ParquetValueReader<Long> position() {\n    return new PositionReader();\n  }","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/parquet/src/main/java/org/apache/iceberg/parquet/ParquetValueReaders.java#L137-L173","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before: file written with a nonstandard timestamp unit\nTypes.NestedField.field(\"ts\", Types.TimestampType.withoutZone()) // backed by unsupported unit\n// after: rewrite the file with a supported unit (e.g. MICROS)\nnew ParquetAvroValueWriters.TimestampMicrosWriter(column);\n// or upgrade iceberg-parquet to a version that maps the unit","handlingStrategy":"validation","validationCode":"LogicalTypeAnnotation la = desc.getPrimitiveType().getLogicalTypeAnnotation();\nif (la instanceof TimestampLogicalTypeAnnotation) {\n  TimestampLogicalTypeAnnotation ts = (TimestampLogicalTypeAnnotation) la;\n  if (ts.getUnit() != TimeUnit.MILLIS && ts.getUnit() != TimeUnit.MICROS && ts.getUnit() != TimeUnit.NANOS) {\n    throw new IllegalArgumentException(\"Timestamp unit not supported: \" + ts.getUnit());\n  }\n}","typeGuard":"boolean isSupportedTimestampUnit(LogicalTypeAnnotation la) {\n  return la instanceof TimestampLogicalTypeAnnotation\n      && EnumSet.of(TimeUnit.MILLIS, TimeUnit.MICROS, TimeUnit.NANOS)\n          .contains(((TimestampLogicalTypeAnnotation) la).getUnit());\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["parquet","timestamp","unsupported-unit"],"backgroundTag":"unsupported-enum-value","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}