apache/iceberg · error · 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
StructInternalRow.getLong converts the underlying Iceberg struct field to a Spark BIGINT/TIMESTAMP long. It supports Long, OffsetDateTime (timestamp), Duration-equivalent nanos, and LocalDate (date-to-epoch-day); any other runtime type triggers this IllegalStateException naming the actual class.
Source
Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java:153
return (int) ((LocalDate) integer).toEpochDay();
} else {
throw new IllegalStateException(
"Unknown type for int field. Type name: " + integer.getClass().getName());
}
}
@Override
public long getLong(int ordinal) {
Object longVal = struct.get(ordinal, 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 {
throw new IllegalStateException(
"Unknown type for long field. Type name: " + longVal.getClass().getName());
}
}
@Override
public float getFloat(int ordinal) {
return struct.get(ordinal, Float.class);
}
@Override
public double getDouble(int ordinal) {
return struct.get(ordinal, Double.class);
}
@Override
public Decimal getDecimal(int ordinal, int precision, int scale) {
return isNullAt(ordinal) ? null : getDecimalInternal(ordinal);
}View on GitHub (pinned to 86d9c8fc54)
Solutions
- Align the expected Spark schema with the table's actual field types (e.g. read a Timestamp column with getLong only if the producer yields OffsetDateTime)
- Fix the producer/row wrapper to store the type Iceberg's conversion expects (Long for long, OffsetDateTime for timestamp, LocalDate for date)
- Print/inspect the class name from the message to identify what is actually stored and adapt accordingly
- Upgrade Iceberg if your version's timestamp Java mapping differs from the reader's expectations
Example fix
// before
row.getLong(tsOrdinal); // stored LocalTime -> IllegalStateException
// after
Object v = row.get(tsOrdinal, sparkType); // confirm stored class first
long nanos = v instanceof OffsetDateTime
? Duration.between(Instant.EPOCH, (OffsetDateTime) v).toNanos() / 1000
: (Long) v; Defensive patterns
Strategy: type-guard
Validate before calling
Object v = struct.get(pos, javaClass);
if (!(v instanceof Long) && !(v instanceof OffsetDateTime) && !(v instanceof LocalDate)) {
throw new IllegalStateException("expected Long/OffsetDateTime/LocalDate for long field, got " + v.getClass());
} Type guard
boolean isLongBacked(Object v) {
return v instanceof Long || v instanceof OffsetDateTime || v instanceof LocalDate;
} Try / catch
try { long l = row.getLong(ordinal); } catch (IllegalStateException e) { /* read the class name from the message and correct schema/producer */ } Prevention
- Match timestamp field mappings (TimestampType vs LongType) exactly between producer and reader
- Avoid writing Timestamp columns and reading them with a LongType expected schema (or vice versa)
- Pin a single Iceberg version across the pipeline so Java-class mappings agree
When it happens
Trigger: Expected schema says LongType/TimestampType at the ordinal but the struct holds a different Java object (e.g. Integer, BigDecimal, LocalTime) — a mismatch between the declared read schema and the actual stored Java classes.
Common situations: Timestamp vs timestamp_ntz vs time mapping confusion; wrong schema passed to Spark scan; Iceberg version differences in the Java class chosen for timestamp types (LocalDateTime vs OffsetDateTime vs Long).
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 long field. Type name: ${longVal.getClass()
- Unknown type for int field. Type name: ${integer.getClass().
- Unknown type for binary field. Type name: ${bytes.getClass()
- Unknown type for long field. Type name: + longVal.getClass()
- Unknown type for int field. Type name: " + integer.getClass(
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/dcab927504c5d82e.
Report an issue: GitHub.