apache/iceberg · error · IllegalStateException
Unknown type for long field. Type name:
Error message
Unknown type for long field. Type name:
What it means
StructRowData.getLong converts a struct field into a Flink long, accepting Long, LocalTime (nanos of day), LocalDateTime, OffsetDateTime and Instant (as microseconds). Any other class triggers this IllegalStateException. It means the stored value's Java class does not correspond to the Iceberg long/time/timestamp field it occupies.
Solutions
- Inspect the class name in the message and ensure long/timestamp fields are written as Long or the supported java.time types.
- Confirm the Iceberg field is LongType/TimestampType as declared in the schema.
- Convert the value to the expected type in the producing pipeline before writing.
Example fix
// before row.setField(pos, someTimestamp); // java.sql.Timestamp not supported here // after row.setField(pos, someTimestamp.toLocalDateTime());
Defensive patterns
Strategy: type-guard
Validate before calling
Object v = struct.getField(pos);
if (!(v instanceof Long || v instanceof LocalTime || v instanceof LocalDateTime || v instanceof OffsetDateTime || v instanceof Instant)) {
throw new IllegalArgumentException("Unexpected class for long field: " + v.getClass());
} Type guard
boolean isLongCompatible(Object v) {
return v instanceof Long || v instanceof LocalTime || v instanceof LocalDateTime
|| v instanceof OffsetDateTime || v instanceof Instant;
} Try / catch
try {
long value = rowData.getLong(pos);
} catch (IllegalStateException e) {
// inspect the class name in the message and convert upstream
} Prevention
- Store LongType fields as java.lang.Long, never Integer or String.
- Use java.time types (LocalDateTime/OffsetDateTime) for timestamp fields.
- Add pre-read assertions in converters between Iceberg schema and Java objects.
When it happens
Trigger: Calling getLong(pos) where the field object is, e.g., an Integer, String or BigDecimal instead of Long or a supported time type.
Common situations: Writers producing Integer for LongType fields; timestamps stored as String or Timestamp objects rather than the expected java.time classes; mismatched Flink LogicalType vs Iceberg type when bridging.
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:
- errMsg(variant, "double")
- errMsg(variant, "int")
- errMsg(variant, "long")
- errMsg(variant, "timestamp")
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/4026c28ab3e13b0a.
Report an issue: GitHub.
Appendix: source
Thrown at flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/data/StructRowData.java:152
@Override
public long getLong(int pos) {
Object longVal = struct.get(pos, Object.class);
if (longVal instanceof Long) {
return (long) longVal;
} else if (longVal instanceof OffsetDateTime) {
return Duration.between(Instant.EPOCH, (OffsetDateTime) longVal).toNanos() / 1000;
} else if (longVal instanceof LocalDate) {
return ((LocalDate) longVal).toEpochDay();
} else if (longVal instanceof LocalTime) {
return ((LocalTime) longVal).toNanoOfDay();
} else if (longVal instanceof LocalDateTime) {
return Duration.between(Instant.EPOCH, ((LocalDateTime) longVal).atOffset(ZoneOffset.UTC))
.toNanos()
/ 1000;
} else {
throw new IllegalStateException(
"Unknown type for long field. Type name: " + longVal.getClass().getName());
}
}
@Override
public float getFloat(int pos) {
return struct.get(pos, Float.class);
}
@Override
public double getDouble(int pos) {
return struct.get(pos, Double.class);
}
@Override
public StringData getString(int pos) {
return isNullAt(pos) ? null : getStringDataInternal(pos);
}View on GitHub (pinned to 86d9c8fc54)