apache/iceberg · error · UnsupportedOperationException

Not implemented for variant

Error message

Not implemented for variant

What it means

ParquetWithSparkSchemaVisitor.variant is the hook for visiting Spark Variant columns in Parquet schemas, and the base implementation throws UnsupportedOperationException because variant handling is not implemented in the visitor. Subclasses are expected to override it; hitting this means the read path encountered a variant column without an override.

Source

Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/data/ParquetWithSparkSchemaVisitor.java:236

  public T struct(StructType sStruct, GroupType struct, List<T> fields) {
    return null;
  }

  public T list(ArrayType sArray, GroupType array, T element) {
    return null;
  }

  public T map(MapType sMap, GroupType map, T key, T value) {
    return null;
  }

  public T primitive(DataType sPrimitive, PrimitiveType primitive) {
    return null;
  }

  public T variant(VariantType sVariant, GroupType variant) {
    throw new UnsupportedOperationException("Not implemented for variant");
  }

  protected String[] currentPath() {
    return Lists.newArrayList(fieldNames.descendingIterator()).toArray(new String[0]);
  }

  protected String[] path(String name) {
    List<String> list = Lists.newArrayList(fieldNames.descendingIterator());
    list.add(name);
    return list.toArray(new String[0]);
  }
}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Upgrade to an Iceberg version whose Parquet reader supports variant columns
  2. Exclude the variant column from the read projection (select other columns only)
  3. Override variant() in your custom visitor subclass with a real implementation
  4. Rewrite the column to a supported type if variant support is unavailable in your runtime

Example fix

// before: custom visitor without variant override
new MyVisitor() { ... } // inherits throwing variant()
// after
@Override
public T variant(VariantType sVariant, GroupType variant) {
  return visitVariant(variant); // real implementation
}
Defensive patterns

Strategy: try-catch

Validate before calling

boolean hasVariant = table.schema().columns().stream()
    .anyMatch(c -> c.type().typeId() == Type.TypeID.VARIANT);
if (hasVariant) { /* ensure runtime supports variant or exclude the column */ }

Type guard

if (schema instanceof VariantType) { /* route to variant-aware visitor */ }

Try / catch

try { ParquetWithSparkSchemaVisitor.visit(schema, type, visitor); } catch (UnsupportedOperationException e) { if (e.getMessage().contains("variant")) { /* exclude column or upgrade */ } else { throw e; } }

Prevention

When it happens

Trigger: Reading/walking a Parquet file whose Spark schema contains a VariantType column using ParquetWithSparkSchemaVisitor (or a subclass that doesn't override variant).

Common situations: Reading tables written with Iceberg variant type (spec v3) using a Spark read path whose visitor hasn't implemented variant support; custom visitor subclasses extending the base without implementing variant.

Related errors


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