{"record":{"id":"bb88b88f61dd7861","repo":"apache/iceberg","slug":"unknown-type-for-timestamp-ns-timeval-getclass","errorCode":null,"errorMessage":"Unknown type for timestamp_ns: ${timeVal.getClass()}","messagePattern":"Unknown type for timestamp_ns: (.+?)","errorType":"exception","errorClass":"java.lang.IllegalStateException","httpStatus":null,"severity":"error","filePath":"flink/v2.1/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.1/flink/src/main/java/org/apache/iceberg/flink/data/StructRowData.java#L187-L223","documentation":"StructRowData.getTimestamp(pos) with NanosecondIntervalType converts the stored object into Flink TimestampData. For timestamp_ns it accepts LocalDateTime and Long (nanos since epoch); anything else triggers this IllegalStateException. It is an internal type-conversion failure for nanosecond-precision timestamp columns.","triggerScenarios":"Reading a timestamp_ns column via getTimestamp when the underlying value is neither LocalDateTime nor Long — e.g. a String, TimestampData, or Instant was stored instead.","commonSituations":"Producers writing timestamp_ns as Instant/String into the struct; connectors with incompatible timestamp representations; schema drift after table evolution.","solutions":["Ensure the producer stores LocalDateTime or Long (epoch nanos) for timestamp_ns fields","Convert the value before storing: Instant -> LocalDateTime.ofInstant(instant, ZoneOffset.UTC)","Read with the accessor matching the actual stored type, or normalize the data upstream"],"exampleFix":"// before\nrow.setField(pos, instant); // Instant not accepted for timestamp_ns\n// after\nrow.setField(pos, LocalDateTime.ofInstant(instant, ZoneOffset.UTC));","handlingStrategy":"type-guard","validationCode":"Object v = structRowData.getValue(pos);\nif (!(v instanceof LocalDateTime || v instanceof Long)) {\n  throw new IllegalArgumentException(\"timestamp_ns value must be LocalDateTime or Long(nanos), got: \" + (v == null ? \"null\" : v.getClass()));\n}","typeGuard":"boolean tsNsReadable(Object v) { return v instanceof LocalDateTime || v instanceof Long; }","tryCatchPattern":"try { TimestampData ts = row.getTimestamp(pos, 9); } catch (IllegalStateException e) { if (e.getMessage().startsWith(\"Unknown type for timestamp_ns\")) { /* normalize value to LocalDateTime/Long */ } else throw e; }","preventionTips":["Store timestamp_ns as LocalDateTime or epoch-nanos Long only","Convert Instant values to LocalDateTime before writing","Test nanosecond columns end to end across connectors"],"tags":["flink","rowdata","timestamp-ns","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-14T16:17:12.679Z"}