apache/iceberg · error · IllegalStateException
Unknown type for int field. Type name: + integer.getClass().
Error message
Unknown type for int field. Type name: + integer.getClass().getName()
What it means
StructInternalRow.getInt converts the stored field value to a Spark int, accepting Integer or LocalDate (Iceberg Date). If the stored object is neither (a data/spec mismatch between the Iceberg type and what was stored), it throws IllegalStateException naming the actual class.
Source
Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java:135
public byte getByte(int ordinal) {
return (byte) (int) struct.get(ordinal, Integer.class);
}
@Override
public short getShort(int ordinal) {
return (short) (int) struct.get(ordinal, Integer.class);
}
@Override
public int getInt(int ordinal) {
Object integer = struct.get(ordinal, Object.class);
if (integer instanceof Integer) {
return (int) integer;
} else if (integer instanceof LocalDate) {
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());
}View on GitHub (pinned to 86d9c8fc54)
Solutions
- Check the stored type named in the message and read the field with the matching getter (getLong for long-backed types)
- Align the requested Spark type with the Iceberg schema (Date -> int, Timestamp -> long)
- Rewrite data or refresh metadata if the physical type drifted from the declared schema
Example fix
// before int v = structRow.getInt(dateOrdinal); // stores OffsetDateTime // after long epochDayMicros = structRow.getLong(dateOrdinal); // match stored representation
Defensive patterns
Strategy: type-guard
Validate before calling
Object v = structLike.get(ordinal, null);
if (!(v instanceof Integer || v instanceof LocalDate)) {
throw new IllegalArgumentException("Field " + ordinal + " is not int-compatible: " + v.getClass());
} Type guard
boolean isIntField(Object v) { return v instanceof Integer || v instanceof LocalDate; } Try / catch
try {
return row.getInt(ordinal);
} catch (IllegalStateException e) {
// fall back to getLong/conversion based on the stored type
} Prevention
- Match getters to the Iceberg type: Date -> getInt, Timestamp/Long -> getLong
- Re-check schemas after type promotion or evolution operations
- Log stored field classes when debugging struct reads
When it happens
Trigger: Calling getInt(ordinal) on a StructInternalRow whose underlying struct field holds an object that is not Integer or LocalDate, e.g. a long-backed timestamp stored where an int-typed (Date) column was expected.
Common situations: Schema evolution changing a column type without rewriting data; reading Date data where the struct actually stores a different Java representation; type-promotion mismatches between table schema and read schema.
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()
- Unsupported value for VARIANT in StructInternalRow: ${value.
- Unknown type for int field. Type name: " + integer.getClass(
- Unknown type for int field. Type name: ${integer.getClass().
- Table does not implement %s: %s (%s)
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/b01b5e112e161887.
Report an issue: GitHub.