apache/iceberg · error · UnsupportedOperationException

Complex types currently not supported

Error message

Complex types currently not supported

What it means

SparkValueConverter.convertToSpark (Iceberg internal value -> Spark value) explicitly rejects complex Iceberg types: STRUCT, LIST and MAP branches throw UnsupportedOperationException('Complex types currently not supported'). At the time this converter was written it only translated primitive values, so nested types are refused instead of silently mis-converted.

Solutions

  1. Upgrade to an Iceberg release where nested type conversion is supported for your code path
  2. Flatten the schema (extract struct fields / unnest lists) so only primitive columns flow through this converter
  3. Use the DataFrame-based read/write paths instead of the row-object converter for nested data
  4. Cast nested columns to serialized primitives (e.g. to_json -> string) if a legacy pipeline requires it

Example fix

// before
Object sparkVal = SparkValueConverter.convertToSpark(structType, record); // STRUCT -> throws
// after: flatten first
Dataset<Row> flat = df.select(col("s.a"), col("s.b"));
Defensive patterns

Strategy: type-guard

Validate before calling

static boolean isComplex(Type t) {
  Type.TypeID id = t.typeId();
  return id == Type.TypeID.STRUCT || id == Type.TypeID.LIST || id == Type.TypeID.MAP;
}

Type guard

if (!(type instanceof Types.StructType || type instanceof Types.ListType || type instanceof Types.MapType)) { value = SparkValueConverter.convertToSpark(type, object); }

Try / catch

try {
  value = SparkValueConverter.convertToSpark(type, object);
} catch (UnsupportedOperationException e) {
  if ("Complex types currently not supported".equals(e.getMessage())) { /* flatten or serialize the nested value */ }
  throw e;
}

Prevention

When it happens

Trigger: Calling convertToSpark with an Iceberg Types.StructType, ListType or MapType (e.g. converting values for nested columns, such as during metadata/partition value conversion on a table with nested partition fields).

Common situations: Using older Iceberg versions where nested-column conversion was unimplemented; passing struct/list/map-typed values through APIs that use this converter instead of the full nested conversion paths.

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

Appendix: source

Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/SparkValueConverter.java:132

          record.set(i, convert(fieldType.asMapType(), row.getJavaMap(i)));
          break;
        default:
          record.set(i, convert(fieldType, row.get(i)));
      }
    }
    return record;
  }

  public static Object convertToSpark(Type type, Object object) {
    if (object == null) {
      return null;
    }

    switch (type.typeId()) {
      case STRUCT:
      case LIST:
      case MAP:
        throw new UnsupportedOperationException("Complex types currently not supported");
      case DATE:
        return DateTimeUtils.daysToLocalDate((int) object);
      case TIMESTAMP:
        Types.TimestampType ts = (Types.TimestampType) type.asPrimitiveType();
        if (ts.shouldAdjustToUTC()) {
          return DateTimeUtils.microsToInstant((long) object);
        } else {
          return DateTimeUtils.microsToLocalDateTime((long) object);
        }
      case BINARY:
        return ByteBuffers.toByteArray((ByteBuffer) object);
      case INTEGER:
      case BOOLEAN:
      case LONG:
      case FLOAT:
      case DOUBLE:
      case DECIMAL:
      case STRING:

View on GitHub (pinned to 86d9c8fc54)