apache/iceberg · error · java.lang.IllegalStateException
Unknown type for long field. Type name: ${longVal.getClass()
Error message
Unknown type for long field. Type name: ${longVal.getClass().getName()} What it means
StructRowData.getLong(pos) converts the field at pos to a Flink BIGINT, accepting Long, Date, LocalDate, LocalTime, and LocalDateTime values (converted to epoch units). If the underlying object is any other class, it throws IllegalStateException with the class name. The stored value doesn't match a long-representable Iceberg type.
Source
Thrown at flink/v2.1/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)
Solutions
- Verify the Iceberg schema type for the column is long/date/time/timestamp
- Fix the upstream producer so it stores Long or java.time values
- Use the matching accessor (getString, getTimestamp, getBigDecimal-equivalent) for the real type
Example fix
// before long v = structRowData.getLong(pos); // stored value is BigDecimal // after BigDecimal d = (BigDecimal) structRowData.getValue(pos); long v = d.unscaledValue().longValueExact();
Defensive patterns
Strategy: type-guard
Validate before calling
Object v = structRowData.getValue(pos);
if (!(v instanceof Long || v instanceof LocalDate || v instanceof LocalTime || v instanceof LocalDateTime || v instanceof java.util.Date)) {
throw new IllegalArgumentException("getLong unsupported value at " + pos + ": " + (v == null ? "null" : v.getClass()));
} Type guard
boolean longReadable(Object v) { return v instanceof Long || v instanceof LocalDate || v instanceof LocalTime || v instanceof LocalDateTime || v instanceof java.util.Date; } Try / catch
try { long x = row.getLong(pos); } catch (IllegalStateException e) { if (e.getMessage().startsWith("Unknown type for long field")) { /* use matching accessor */ } else throw e; } Prevention
- Use getLong only for long/date/time/timestamp columns
- Convert producers to emit Long or java.time types
- Assert stored types in connector tests
When it happens
Trigger: Calling getLong on a field whose stored value is not Long/Date/LocalDate/LocalTime/LocalDateTime — e.g. a String, BigDecimal, or TimestampData where the schema expected long/timestamp.
Common situations: Schema/data mismatch from a custom source or connector feeding wrong object types; wrong accessor chosen for a string or decimal column.
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 timestamp_ns: ${timeVal.getClass()}
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/df087452dd969cb9.
Report an issue: GitHub.