apache/iceberg · error · IllegalStateException
Unknown type for int field. Type name: " +…
Error message
Unknown type for int field. Type name: " + integer.getClass().getName()
What it means
StructRowData.getInt converts the Object stored in the wrapped Iceberg StructLike at pos into a Flink INT. It accepts Integer, LocalDate (Date field, converted to epoch day) and LocalTime (Time field, converted to millisecond-of-day); any other runtime type means the struct holds a value inconsistent with an int-typed field and IllegalStateException is thrown with the actual class name.
Solutions
- Verify the Iceberg schema passed to StructRowData matches the actual types of the underlying StructLike data; re-align field positions/types.
- Check what class the error names — the message prints the actual stored type; fix the writer/reader so an int field stores Integer, LocalDate or LocalTime.
- If reading files written by another engine/version, rewrite or re-read with the schema the files were written with.
- Wrap getInt with a pre-check: struct.get(pos, Object.class) type inspection before calling, converting unsupported types explicitly.
Example fix
// before
int v = structRowData.getInt(pos); // IllegalStateException for unexpected type
// after
Object raw = struct.get(pos, Object.class);
int v;
if (raw instanceof Integer i) {
v = i;
} else if (raw instanceof Long l) {
v = Math.toIntExact(l);
} else if (raw instanceof String s) {
v = Integer.parseInt(s);
} else {
v = structRowData.getInt(pos);
} Defensive patterns
Strategy: validation
Validate before calling
Object raw = struct.get(pos, Object.class);
Preconditions.checkArgument(
raw == null || raw instanceof Integer || raw instanceof LocalDate || raw instanceof LocalTime,
"int field holds unexpected type: %s", raw == null ? "null" : raw.getClass()); Type guard
boolean isIntRepresentable(Object v) {
return v instanceof Integer || v instanceof LocalDate || v instanceof LocalTime;
} Try / catch
try {
int v = structRowData.getInt(pos);
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Unknown type for int field")) {
log.error("Schema mismatch on int column at pos {}", pos, e);
throw new SchemaMismatchException(e);
}
throw e;
} Prevention
- Keep the read schema identical to the write schema; validate with a schema-compat check at job start.
- Unit-test StructLike producers so int/date/time fields store Integer/LocalDate/LocalTime.
When it happens
Trigger: Reading a projected/int column via StructRowData.getInt(pos) when the underlying StructLike stores something other than Integer/LocalDate/LocalTime — e.g. a Long or String written by a custom writer or an incompatible schema at read time.
Common situations: Schema drift between the table schema used to write the data and the schema supplied when reading; custom StructLike implementations (e.g. wrapped GenericRecord or Row) storing boxed types outside the expected set; reading Date/Time columns whose backing representation changed across Iceberg versions.
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: " +…
- Unknown type for timestamp_ns: " + timeVal.getClass()
- Cannot convert to struct
- Could not set a field in the RowDataWrapper because rowData…
- errMsg(variant, "double")
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/c4dccf028b5bc325.
Report an issue: GitHub.
Appendix: source
Thrown at flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/data/StructRowData.java:130
}
@Override
public short getShort(int pos) {
return (short) (int) struct.get(pos, Integer.class);
}
@Override
public int getInt(int pos) {
Object integer = struct.get(pos, Object.class);
if (integer instanceof Integer) {
return (int) integer;
} else if (integer instanceof LocalDate localDate) {
return (int) localDate.toEpochDay();
} else if (integer instanceof LocalTime) {
return (int) (((LocalTime) integer).toNanoOfDay() / 1000_000);
} else {
throw new IllegalStateException(
"Unknown type for int field. Type name: " + integer.getClass().getName());
}
}
@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))View on GitHub (pinned to 86d9c8fc54)