apache/iceberg · error · IllegalStateException

Unknown type for int field. Type name:

Error message

Unknown type for int field. Type name: 

What it means

StructInternalRow.getInt validates that the underlying value for an int-typed field is an Integer or LocalDate before converting; any other runtime type triggers this IllegalStateException naming the actual Java class. It guards the unsafe cast from the StructLike value to Spark's int representation.

Source

Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java:140

  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

  1. Align the requested Spark schema with the actual Iceberg schema so int fields hold Integer values
  2. Check for schema evolution drift (e.g. field promoted to long) and refresh the table schema/cache
  3. Log the offending field and type name from the message, then fix the producer that writes the wrong type

Example fix

// before
row.getInt(dateFieldOrdinal); // throws: value is Long
// after
Schema updated = SparkSchemaUtil.convert(sparkSchema); // ensure types align
if (value instanceof Long) { /* reload with corrected schema */ }
Defensive patterns

Strategy: validation

Validate before calling

// Java
Object v = struct.getField(ordinal);
if (!(v instanceof Integer) && !(v instanceof LocalDate)) {
  throw new IllegalStateException("Expected Integer/LocalDate, got " + v.getClass());
}

Type guard

boolean isValidIntFieldValue(Object v) {
  return v instanceof Integer || v instanceof LocalDate;
}

Try / catch

try {
  int i = row.getInt(ordinal);
} catch (IllegalStateException e) {
  if (e.getMessage().startsWith("Unknown type for int field")) {
    // reload with a corrected schema matching the data
  }
  throw e;
}

Prevention

When it happens

Trigger: Reading an int/Date field whose stored value is neither Integer nor LocalDate — e.g. schema drift where the Iceberg schema declares int but the row's value object is a different type (Long, String, etc.).

Common situations: Schema mismatches between the declared Spark/Iceberg schema and actual data, corrupt or wrongly converted rows, or custom data sources producing unexpected boxed types.

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


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/a4f82a8497dca601. Report an issue: GitHub.