{"record":{"id":"ef6f780b4250634e","repo":"apache/iceberg","slug":"unsupported-type-variant-ef6f78","errorCode":null,"errorMessage":"Unsupported type: variant","messagePattern":"Unsupported type: variant","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/avro/AvroCustomOrderSchemaVisitor.java","lineNumber":106,"sourceCode":"\n  public F field(Schema.Field field, Supplier<T> fieldResult) {\n    return null;\n  }\n\n  public T union(Schema union, Iterable<T> options) {\n    return null;\n  }\n\n  public T array(Schema array, Supplier<T> element) {\n    return null;\n  }\n\n  public T map(Schema map, Supplier<T> value) {\n    return null;\n  }\n\n  public T variant(Schema variant, Supplier<T> metadataResult, Supplier<T> valueResult) {\n    throw new UnsupportedOperationException(\"Unsupported type: variant\");\n  }\n\n  public T primitive(Schema primitive) {\n    return null;\n  }\n\n  private static class VisitFuture<T, F> implements Supplier<T> {\n    private final Schema schema;\n    private final AvroCustomOrderSchemaVisitor<T, F> visitor;\n\n    private VisitFuture(Schema schema, AvroCustomOrderSchemaVisitor<T, F> visitor) {\n      this.schema = schema;\n      this.visitor = visitor;\n    }\n\n    @Override\n    public T get() {\n      return visit(schema, visitor);","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/avro/AvroCustomOrderSchemaVisitor.java#L88-L124","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","solutions":["Upgrade to an Iceberg version that supports the variant type (format version 3)","Override the variant() method in your AvroCustomOrderSchemaVisitor subclass to handle the variant type","Exclude or filter variant columns from the schema before visiting/converting","If variant support is not needed, ensure writers do not emit variant columns into Avro files consumed by this reader"],"exampleFix":"// before\nAvroCustomOrderSchemaVisitor<Type> visitor = new MyVisitor(); // no variant override\nType result = AvroCustomOrderSchemaVisitor.visit(schema, visitor); // throws\n\n// after\n@Override\npublic T variant(Schema variant, Supplier<T> metadataResult, Supplier<T> valueResult) {\n  return VariantType.get(); // or another supported representation\n}","handlingStrategy":"validation","validationCode":"if (schema.getFields().stream().anyMatch(f -> f.schema().getLogicalType() instanceof VariantLogicalType)) { throw new IllegalArgumentException(\"Variant fields not supported by this visitor\"); }","typeGuard":"boolean hasVariant(Schema s) { return s.getFields().stream().anyMatch(f -> \"variant\".equals(f.schema().getProp(\"logicalType\"))); }","tryCatchPattern":null,"preventionTips":["Override variant() when subclassing AvroCustomOrderSchemaVisitor for schemas that may contain v3 types","Filter variant columns from projected schemas before visiting","Keep Iceberg version current with the table format version in use"],"tags":["avro","schema","unsupported-type","variant"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}