apache/iceberg · error · IllegalStateException

Unknown type for long field. Type name: " +…

Error message

Unknown type for long field. Type name: " + longVal.getClass().getName()

What it means

StructRowData.getLong converts the Object in the wrapped StructLike at pos into a Flink BIGINT. It accepts Long plus Iceberg's time-oriented java.time representations: OffsetDateTime (timestamptz), LocalDate (date), LocalTime (time), and LocalDateTime (timestamp). Any other stored type triggers IllegalStateException naming the class, meaning the field's runtime type doesn't match a long-typed Iceberg column.

Solutions

  1. Inspect the class name in the message and convert that stored type to Long (or OffsetDateTime/LocalDate/LocalTime/LocalDateTime) at the source.
  2. Ensure the read schema matches the files' written schema so long columns are decoded as the expected representations.
  3. If using a custom StructLike/wrapper, normalize timestamp/date values to java.time types before wrapping in StructRowData.
  4. Pre-convert values yourself: read via struct.get(pos, Object.class), map to long, and avoid relying on StructRowData's limited instanceof chain.

Example fix

// before
long v = structRowData.getLong(pos); // fails when stored as java.util.Date

// after
Object raw = struct.get(pos, Object.class);
long v = (raw instanceof java.util.Date d)
    ? d.toInstant().toEpochMilli() * 1000L
    : structRowData.getLong(pos);
Defensive patterns

Strategy: validation

Validate before calling

Object raw = struct.get(pos, Object.class);
Preconditions.checkArgument(
    raw == null || raw instanceof Long || raw instanceof OffsetDateTime
        || raw instanceof LocalDate || raw instanceof LocalTime || raw instanceof LocalDateTime,
    "long field holds unexpected type: %s", raw == null ? "null" : raw.getClass());

Type guard

boolean isLongRepresentable(Object v) {
  return v instanceof Long || v instanceof OffsetDateTime || v instanceof LocalDate
      || v instanceof LocalTime || v instanceof LocalDateTime;
}

Try / catch

try {
  long v = structRowData.getLong(pos);
} catch (IllegalStateException e) {
  if (e.getMessage().startsWith("Unknown type for long field")) {
    log.error("Long column at pos {} stores incompatible type", pos, e);
    throw new SchemaMismatchException(e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Reading a long/bigint, timestamp, date or time column via StructRowData.getLong(pos) when the StructLike stores an unexpected object type (e.g. Integer, BigDecimal, String, java.util.Date) instead of Long or one of the supported java.time types.

Common situations: Custom readers/writers that populate StructLike rows with java.util.Date or String timestamps; schema mismatch between reader schema and physical data; third-party StructLike adapters (Hive/Spark records) mapping timestamp columns to types Iceberg's Flink reader doesn't expect.

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/4c2cf2efa008f68a. Report an issue: GitHub.

Appendix: source

Thrown at flink/v2.2/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)