{"record":{"id":"5b4e75b593f1c489","repo":"apache/iceberg","slug":"unknown-type-for-timestamp-ns","errorCode":null,"errorMessage":"Unknown type for timestamp_ns: ","messagePattern":"Unknown type for timestamp_ns: ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/data/StructRowData.java","lineNumber":205,"sourceCode":"\n  @Override\n  public TimestampData getTimestamp(int pos, int precision) {\n    if (precision > 6) {\n      Object timeVal = struct.get(pos, Object.class);\n      if (timeVal instanceof OffsetDateTime) {\n        OffsetDateTime odt = (OffsetDateTime) timeVal;\n        return TimestampData.fromEpochMillis(\n            odt.toInstant().toEpochMilli(), odt.getNano() % 1_000_000);\n      } else if (timeVal instanceof LocalDateTime) {\n        LocalDateTime ldt = (LocalDateTime) timeVal;\n        return TimestampData.fromEpochMillis(\n            ldt.toInstant(ZoneOffset.UTC).toEpochMilli(), ldt.getNano() % 1_000_000);\n      } else if (timeVal instanceof Long) {\n        long timeLong = (Long) timeVal;\n        return TimestampData.fromEpochMillis(\n            Math.floorDiv(timeLong, 1_000_000L), (int) Math.floorMod(timeLong, 1_000_000L));\n      } else {\n        throw new IllegalStateException(\"Unknown type for timestamp_ns: \" + timeVal.getClass());\n      }\n    }\n    long timeLong = getLong(pos);\n    return TimestampData.fromEpochMillis(\n        Math.floorDiv(timeLong, 1000L), (int) Math.floorMod(timeLong, 1000L) * 1000);\n  }\n\n  @Override\n  public <T> RawValueData<T> getRawValue(int pos) {\n    throw new UnsupportedOperationException(\"Not supported yet.\");\n  }\n\n  @Override\n  public byte[] getBinary(int pos) {\n    return isNullAt(pos) ? null : getBinaryInternal(pos);\n  }\n\n  private byte[] getBinaryInternal(int pos) {","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/data/StructRowData.java#L187-L223","documentation":"Within StructRowData.getTimestamp, when the Iceberg field is timestamp_ns, the stored value must be LocalDateTime (micros branch), Instant, or Long (nanoseconds). Any other class raises this IllegalStateException. It signals a nanosecond-timestamp value stored in an unexpected Java representation.","triggerScenarios":"Calling getTimestamp(pos) on a timestamp_ns field whose value object is not LocalDateTime, Instant or Long, e.g. a java.sql.Timestamp or String.","commonSituations":"Reading data written by custom or third-party converters that materialize nanosecond timestamps as java.sql.Timestamp; schema evolved from timestamp (micros) to timestamp_ns while values kept old representations.","solutions":["Ensure timestamp_ns values are stored as Long nanos, Instant, or LocalDateTime.","Convert java.sql.Timestamp values to LocalDateTime/Instant before writing.","Verify the Flink LogicalType precision (TimestampType(9) for timestamp_ns) matches the Iceberg field."],"exampleFix":"// before\nrow.setField(pos, sqlTimestamp);\n\n// after\nrow.setField(pos, sqlTimestamp.toInstant());","handlingStrategy":"type-guard","validationCode":"if (type.equals(Types.TimestampNanoType.get())) {\n  Object v = struct.getField(pos);\n  if (!(v instanceof LocalDateTime || v instanceof Instant || v instanceof Long)) {\n    throw new IllegalArgumentException(\"Bad timestamp_ns representation: \" + v.getClass());\n  }\n}","typeGuard":"boolean isNanoTimestampCompatible(Object v) {\n  return v instanceof LocalDateTime || v instanceof Instant || v instanceof Long;\n}","tryCatchPattern":"try {\n  TimestampData ts = rowData.getTimestamp(pos, 9);\n} catch (IllegalStateException e) {\n  // convert the offending value (e.g. java.sql.Timestamp -> Instant) before retrying\n}","preventionTips":["Use TimestampType(9)/timestamp_ns-compatible representations (Long nanos, Instant, LocalDateTime).","Convert legacy java.sql.Timestamp values when migrating to nanosecond timestamps.","Keep Flink LogicalType precision in sync with the Iceberg timestamp precision."],"tags":["flink","timestamp","type-mismatch"],"backgroundTag":"type-mismatch","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"}