apache/iceberg · error · UnsupportedOperationException

Unsupported type: interval

Error message

Unsupported type: interval

What it means

Iceberg's StructInternalRow does not support Spark's CalendarInterval type; getInterval unconditionally throws UnsupportedOperationException. The Iceberg type system has no interval type, so interval values cannot be represented in an Iceberg-backed InternalRow.

Solutions

  1. Remove or transform interval columns before they reach Iceberg — intervals are not part of the Iceberg spec.
  2. Convert the interval to a supported type, e.g. store the amount as an integer/long (days, months, or seconds).
  3. Cast derived intervals upstream to a duration representation before reading/writing via Iceberg.
  4. Do not attempt catch-and-recover: the type is fundamentally unsupported for Iceberg rows.

Example fix

// before
df.withColumn("iv", expr("interval 3 days")).writeTo(table).create();
// after
df.withColumn("interval_days", lit(3)).writeTo(table).create();
Defensive patterns

Strategy: validation

Validate before calling

for (StructField f : df.schema().fields()) {
  if (f.dataType() instanceof CalendarIntervalType) {
    throw new IllegalArgumentException("Iceberg does not support interval column: " + f.name());
  }
}

Type guard

static boolean isIntervalColumn(StructField f) {
  return f.dataType() instanceof CalendarIntervalType;
}

Try / catch

try {
  df.writeTo(table).create();
} catch (UnsupportedOperationException e) {
  if (e.getMessage().contains("interval")) {
    // drop/transform the interval column and retry
  } else throw e;
}

Prevention

When it happens

Trigger: Calling getInterval(ordinal) on a StructInternalRow — e.g. a Spark query materializing an interval-typed field against an Iceberg table, or attempting to write computed CalendarInterval columns into an Iceberg table.

Common situations: Queries that add interval columns (e.g. via expr("interval 3 days") or date arithmetic) and then write to Iceberg; schema evolution or views introducing interval columns over Iceberg sources; UDFs returning intervals read through the Iceberg scan path.

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

Appendix: source

Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java:206

  }

  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)