apache/iceberg · error · java.lang.UnsupportedOperationException
Not implemented for variant
Error message
Not implemented for variant
What it means
The SparkTypeToIcebergType visitor's default variant() hook has no implementation; any concrete visitor that does not override it will throw when the schema contains a Spark VariantType column. This is an extension-point guard: subclass visitors must handle variant or reject it explicitly.
Source
Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/SparkTypeVisitor.java:64
visit(((MapType) type).keyType(), visitor),
visit(((MapType) type).valueType(), visitor));
} else if (type instanceof ArrayType) {
return visitor.array((ArrayType) type, visit(((ArrayType) type).elementType(), visitor));
} else if (type instanceof VariantType) {
return visitor.variant((VariantType) type);
} else if (type instanceof UserDefinedType) {
throw new UnsupportedOperationException("User-defined types are not supported");
} else {
return visitor.atomic(type);
}
}
public T variant(VariantType variant) {
throw new UnsupportedOperationException("Not implemented for variant");
}
public T struct(StructType struct, List<T> fieldResults) {
return null;
}
public T field(StructField field, T typeResult) {
return null;
}
public T array(ArrayType array, T elementResult) {
return null;
}
public T map(MapType map, T keyResult, T valueResult) {
return null;
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Override variant(VariantType variant) in your visitor subclass and return the desired mapping (e.g. Types.VariantType.get())
- Reject variant columns earlier by filtering them out of the schema before applying the visitor
- Do not use the default visitor directly; subclass it and handle all relevant types
Example fix
// before
class MyVisitor extends SparkTypeVisitor<Type> { }
// after
class MyVisitor extends SparkTypeVisitor<Type> {
@Override
public Type variant(VariantType variant) {
return Types.VariantType.get();
}
} Defensive patterns
Strategy: type-guard
Validate before calling
// before applying visitor
boolean hasVariant = false;
for (StructField f : sparkSchema.fields()) {
if (f.dataType().typeName().equalsIgnoreCase("variant")) { hasVariant = true; break; }
}
if (hasVariant) throw new IllegalArgumentException("Variant columns require a visitor that implements variant()"); Type guard
static boolean hasVariantColumn(StructType schema) {
for (StructField f : schema.fields()) {
if (f.dataType() instanceof org.apache.spark.sql.types.VariantType) return true;
}
return false;
} Try / catch
try { visitor.apply(type) } catch (UnsupportedOperationException e) { if (e.getMessage().contains("Not implemented for variant")) { /* fallback: drop/reject variant columns */ } else throw e; } Prevention
- Always override variant() in SparkTypeVisitor subclasses
- Check Spark 4.x variant columns early in schema validation
When it happens
Trigger: A custom TypeVisitor subclass (extending SparkTypeVisitor) is applied to a Spark schema containing a VariantType column (Spark 4.x variant type) and the subclass does not override variant(VariantType).
Common situations: Upgrading to Spark 4.x where variant columns appear in schemas read from Parquet or defined via VARIANT literal; authors of custom type visitors forgetting to implement the new variant callback.
Related errors
- Not implemented for variant
- Not implemented for variant
- Not implemented for variant
- Not implemented for variant
- Unsupported type: variant
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/9fa34e1ecc05ebdb.
Report an issue: GitHub.