apache/iceberg · error · UnsupportedOperationException

Unsupported type: variant

Error message

Unsupported type: variant

What it means

AvroSchemaVisitor.variant is the hook invoked when the visitor encounters an Iceberg Variant type in an Avro schema. The base implementation throws UnsupportedOperationException because plain Avro has no Variant representation; only visitors that explicitly support variants override this method.

Source

Thrown at core/src/main/java/org/apache/iceberg/avro/AvroSchemaVisitor.java:119

  public T record(Schema record, List<String> names, List<T> fields) {
    return null;
  }

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

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

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

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

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

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Upgrade to an Iceberg version that supports the Variant type and its Avro mapping
  2. Override variant() in your AvroSchemaVisitor subclass with the appropriate handling for metadata/value results
  3. Exclude variant columns from the read projection if variants are not needed
  4. If the engine lacks Variant support, cast/convert the column to a supported type at write time

Example fix

// before: visitor without variant support
new AvroSchemaVisitor<Type>() {
  @Override public Type record(Schema rec, List<String> names, List<Type> types) { ... }
  @Override public Type primitive(Schema p) { ... }
}
// after: override variant
new AvroSchemaVisitor<Type>() {
  @Override public Type record(Schema rec, List<String> names, List<Type> types) { ... }
  @Override public Type primitive(Schema p) { ... }
  @Override public Type variant(Schema s, Type metadata, Type value) {
    return Types.VariantType.get();
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

boolean hasVariant = schema.columns().stream()
    .anyMatch(f -> f.schema().type() instanceof Types.VariantType);
if (hasVariant && !supportsVariant()) {
  throw new IllegalStateException("Reader stack does not support Variant columns");
}

Try / catch

try {
  return AvroSchemaUtil.convert(avroSchema, tableSchema.asStruct());
} catch (UnsupportedOperationException e) {
  if (e.getMessage() != null && e.getMessage().contains("variant")) {
    return convertWithoutVariantColumns(avroSchema, tableSchema);
  }
  throw e;
}

Prevention

When it happens

Trigger: Visiting (e.g. via AvroSchemaUtil.convert or a custom AvroSchemaVisitor subclass that does not override variant()) an Avro record structured as an Iceberg Variant (metadata + value fields), typically in Avro files written for a v3 table containing variant columns.

Common situations: Reading Avro files containing Variant columns with a reader stack (reader function/visitor) built before Variant support; custom projection visitors that handle record/map/list/primitives but not variant; engine or library version too old for Variant types.

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