apache/iceberg · error · UnsupportedOperationException

Unsupported type: variant

Error message

Unsupported type: variant

What it means

AvroCustomOrderSchemaVisitor.variant is the default handler for Avro's 'variant' logical type in schema traversal. The base visitor has no default handling for variant types, so encountering one during a schema visit throws UnsupportedOperationException. This guards callers from silently producing incorrect conversions of variant columns.

Source

Thrown at core/src/main/java/org/apache/iceberg/avro/AvroCustomOrderSchemaVisitor.java:106

  public F field(Schema.Field field, Supplier<T> fieldResult) {
    return null;
  }

  public T union(Schema union, Iterable<T> options) {
    return null;
  }

  public T array(Schema array, Supplier<T> element) {
    return null;
  }

  public T map(Schema map, Supplier<T> value) {
    return null;
  }

  public T variant(Schema variant, Supplier<T> metadataResult, Supplier<T> valueResult) {
    throw new UnsupportedOperationException("Unsupported type: variant");
  }

  public T primitive(Schema primitive) {
    return null;
  }

  private static class VisitFuture<T, F> implements Supplier<T> {
    private final Schema schema;
    private final AvroCustomOrderSchemaVisitor<T, F> visitor;

    private VisitFuture(Schema schema, AvroCustomOrderSchemaVisitor<T, F> visitor) {
      this.schema = schema;
      this.visitor = visitor;
    }

    @Override
    public T get() {
      return visit(schema, visitor);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Upgrade to an Iceberg version that supports the variant type (format version 3)
  2. Override the variant() method in your AvroCustomOrderSchemaVisitor subclass to handle the variant type
  3. Exclude or filter variant columns from the schema before visiting/converting
  4. If variant support is not needed, ensure writers do not emit variant columns into Avro files consumed by this reader

Example fix

// before
AvroCustomOrderSchemaVisitor<Type> visitor = new MyVisitor(); // no variant override
Type result = AvroCustomOrderSchemaVisitor.visit(schema, visitor); // throws

// after
@Override
public T variant(Schema variant, Supplier<T> metadataResult, Supplier<T> valueResult) {
  return VariantType.get(); // or another supported representation
}
Defensive patterns

Strategy: validation

Validate before calling

if (schema.getFields().stream().anyMatch(f -> f.schema().getLogicalType() instanceof VariantLogicalType)) { throw new IllegalArgumentException("Variant fields not supported by this visitor"); }

Type guard

boolean hasVariant(Schema s) { return s.getFields().stream().anyMatch(f -> "variant".equals(f.schema().getProp("logicalType"))); }

Prevention

When it happens

Trigger: Visiting (or converting) an Avro schema that contains a field of Avro variant type, e.g. via AvroSchemaUtil.visit or schema conversion to/from Iceberg types, when the concrete visitor subclass does not override variant().

Common situations: Reading Iceberg v3 tables containing variant columns through Avro-based readers; converting an Avro schema written by a newer writer that supports variant into Iceberg types; older client versions encountering newer metadata.

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