apache/iceberg · error · java.lang.IllegalStateException
Unknown type for timestamp_ns: ${timeVal.getClass()}
Error message
Unknown type for timestamp_ns: ${timeVal.getClass()} What it means
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.
Source
Thrown at flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/data/StructRowData.java:205
@Override
public TimestampData getTimestamp(int pos, int precision) {
if (precision > 6) {
Object timeVal = struct.get(pos, Object.class);
if (timeVal instanceof OffsetDateTime) {
OffsetDateTime odt = (OffsetDateTime) timeVal;
return TimestampData.fromEpochMillis(
odt.toInstant().toEpochMilli(), odt.getNano() % 1_000_000);
} else if (timeVal instanceof LocalDateTime) {
LocalDateTime ldt = (LocalDateTime) timeVal;
return TimestampData.fromEpochMillis(
ldt.toInstant(ZoneOffset.UTC).toEpochMilli(), ldt.getNano() % 1_000_000);
} else if (timeVal instanceof Long) {
long timeLong = (Long) timeVal;
return TimestampData.fromEpochMillis(
Math.floorDiv(timeLong, 1_000_000L), (int) Math.floorMod(timeLong, 1_000_000L));
} else {
throw new IllegalStateException("Unknown type for timestamp_ns: " + timeVal.getClass());
}
}
long timeLong = getLong(pos);
return TimestampData.fromEpochMillis(
Math.floorDiv(timeLong, 1000L), (int) Math.floorMod(timeLong, 1000L) * 1000);
}
@Override
public <T> RawValueData<T> getRawValue(int pos) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public byte[] getBinary(int pos) {
return isNullAt(pos) ? null : getBinaryInternal(pos);
}
private byte[] getBinaryInternal(int pos) {View on GitHub (pinned to 86d9c8fc54)
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
Example fix
// before row.setField(pos, instant); // Instant not accepted for timestamp_ns // after row.setField(pos, LocalDateTime.ofInstant(instant, ZoneOffset.UTC));
Defensive patterns
Strategy: type-guard
Validate before calling
Object v = structRowData.getValue(pos);
if (!(v instanceof LocalDateTime || v instanceof Long)) {
throw new IllegalArgumentException("timestamp_ns value must be LocalDateTime or Long(nanos), got: " + (v == null ? "null" : v.getClass()));
} Type guard
boolean tsNsReadable(Object v) { return v instanceof LocalDateTime || v instanceof Long; } Try / catch
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; } Prevention
- 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
When it happens
Trigger: 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.
Common situations: Producers writing timestamp_ns as Instant/String into the struct; connectors with incompatible timestamp representations; schema drift after table evolution.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Unknown type for int field. Type name: ${className}
- Unknown type for long field. Type name: ${className}
- Unknown type for timestamp_ns: ${class}
- Unknown type for int field. Type name: ${integer.getClass().
- Unknown type for long field. Type name: ${longVal.getClass()
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/bb88b88f61dd7861.
Report an issue: GitHub.