apache/iceberg · error · UnsupportedOperationException

Unsupported type: interval

Error message

Unsupported type: interval

What it means

StructInternalRow wraps Iceberg InternalRow data into a Spark InternalRow. CalendarInterval (Spark's INTERVAL type) is not supported by Iceberg's type system, so getInterval unconditionally throws UnsupportedOperationException. Iceberg has no interval type, so no value can ever be provided here.

Solutions

  1. Remove interval-typed fields from the query projection over the Iceberg table
  2. Compute intervals in Spark after reading, from supported Iceberg types (long/int), rather than expecting an interval column
  3. Upgrade Iceberg: newer versions may add support for interval via Spark compatibility layers
  4. If this is your own wrapping code, use Spark's GenericInternalRow for rows containing intervals instead of StructInternalRow

Example fix

// before
row.getInterval(0); // throws
// after
long months = row.getLong(0); // store interval components in supported numeric columns
java.time.Period p = java.time.Period.ofMonths((int) months);
Defensive patterns

Strategy: validation

Validate before calling

if (schema.fields().stream().anyMatch(f -> f.dataType() instanceof CalendarIntervalType)) {
  throw new IllegalArgumentException("Iceberg StructInternalRow does not support interval columns; project them out");
}

Type guard

static boolean hasIntervalField(StructType schema) {
  return java.util.Arrays.stream(schema.fields())
      .anyMatch(f -> f.dataType() instanceof CalendarIntervalType);
}

Prevention

When it happens

Trigger: A Spark job reads an Iceberg table where the projected schema causes Spark to call getInterval on the wrapped row — e.g. schema evolution/type inference paths or a query referencing an interval-typed expression backed by this row adapter.

Common situations: Queries combining Iceberg scans with Spark INTERVAL columns, or custom code casting StructInternalRow rows to a schema containing CalendarInterval fields.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java:208

  }

  private byte[] getBinaryInternal(int ordinal) {
    Object bytes = struct.get(ordinal, Object.class);

    // should only be either ByteBuffer or byte[]
    if (bytes instanceof ByteBuffer) {
      return ByteBuffers.toByteArray((ByteBuffer) bytes);
    } else if (bytes instanceof byte[]) {
      return (byte[]) bytes;
    } else {
      throw new IllegalStateException(
          "Unknown type for binary field. Type name: " + bytes.getClass().getName());
    }
  }

  @Override
  public CalendarInterval getInterval(int ordinal) {
    throw new UnsupportedOperationException("Unsupported type: interval");
  }

  @Override
  public InternalRow getStruct(int ordinal, int numFields) {
    return isNullAt(ordinal) ? null : getStructInternal(ordinal);
  }

  private InternalRow getStructInternal(int ordinal) {
    return new StructInternalRow(
        type.fields().get(ordinal).type().asStructType(), struct.get(ordinal, StructLike.class));
  }

  @Override
  public ArrayData getArray(int ordinal) {
    return isNullAt(ordinal) ? null : getArrayInternal(ordinal);
  }

  private ArrayData getArrayInternal(int ordinal) {

View on GitHub (pinned to 86d9c8fc54)