apache/iceberg · error · IllegalStateException
Unknown type for long field. Type name: " +…
Error message
Unknown type for long field. Type name: " + longVal.getClass().getName()
What it means
StructRowData.getLong converts the Object in the wrapped StructLike at pos into a Flink BIGINT. It accepts Long plus Iceberg's time-oriented java.time representations: OffsetDateTime (timestamptz), LocalDate (date), LocalTime (time), and LocalDateTime (timestamp). Any other stored type triggers IllegalStateException naming the class, meaning the field's runtime type doesn't match a long-typed Iceberg column.
Solutions
- Inspect the class name in the message and convert that stored type to Long (or OffsetDateTime/LocalDate/LocalTime/LocalDateTime) at the source.
- Ensure the read schema matches the files' written schema so long columns are decoded as the expected representations.
- If using a custom StructLike/wrapper, normalize timestamp/date values to java.time types before wrapping in StructRowData.
- Pre-convert values yourself: read via struct.get(pos, Object.class), map to long, and avoid relying on StructRowData's limited instanceof chain.
Example fix
// before
long v = structRowData.getLong(pos); // fails when stored as java.util.Date
// after
Object raw = struct.get(pos, Object.class);
long v = (raw instanceof java.util.Date d)
? d.toInstant().toEpochMilli() * 1000L
: structRowData.getLong(pos); Defensive patterns
Strategy: validation
Validate before calling
Object raw = struct.get(pos, Object.class);
Preconditions.checkArgument(
raw == null || raw instanceof Long || raw instanceof OffsetDateTime
|| raw instanceof LocalDate || raw instanceof LocalTime || raw instanceof LocalDateTime,
"long field holds unexpected type: %s", raw == null ? "null" : raw.getClass()); Type guard
boolean isLongRepresentable(Object v) {
return v instanceof Long || v instanceof OffsetDateTime || v instanceof LocalDate
|| v instanceof LocalTime || v instanceof LocalDateTime;
} Try / catch
try {
long v = structRowData.getLong(pos);
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Unknown type for long field")) {
log.error("Long column at pos {} stores incompatible type", pos, e);
throw new SchemaMismatchException(e);
}
throw e;
} Prevention
- Normalize all timestamp/date/time values to java.time types when populating StructLike rows.
- Never store java.util.Date, String, or BigDecimal in long/timestamp columns.
When it happens
Trigger: Reading a long/bigint, timestamp, date or time column via StructRowData.getLong(pos) when the StructLike stores an unexpected object type (e.g. Integer, BigDecimal, String, java.util.Date) instead of Long or one of the supported java.time types.
Common situations: Custom readers/writers that populate StructLike rows with java.util.Date or String timestamps; schema mismatch between reader schema and physical data; third-party StructLike adapters (Hive/Spark records) mapping timestamp columns to types Iceberg's Flink reader doesn't expect.
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
- errMsg(variant, "timestamp")
- Failed to read Variant
- Unexpected object type for TIMESTAMP logical type. Received
- Unexpected object type for TIMESTAMP logical type. Received
- Unexpected object type for TIMESTAMP logical type…
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/4c2cf2efa008f68a.
Report an issue: GitHub.
Appendix: source
Thrown at flink/v2.2/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)