apache/iceberg · error · UnsupportedOperationException
Unsupported value for VARIANT in StructInternalRow: " + valu
Error message
Unsupported value for VARIANT in StructInternalRow: " + value.getClass()
What it means
toVariantVal converts Iceberg Variant values into Spark VariantVal. It only handles org.apache.iceberg.variants.Variant instances; any other runtime value encountered for a VARIANT-typed field throws UnsupportedOperationException with the value's Java class.
Source
Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java:386
throw new UnsupportedOperationException("Unsupported array element type: " + elementType);
}
}
private static VariantVal toVariantVal(Object value) {
if (value instanceof Variant) {
Variant variant = (Variant) value;
byte[] metadataBytes = new byte[variant.metadata().sizeInBytes()];
ByteBuffer metadataBuffer = ByteBuffer.wrap(metadataBytes).order(ByteOrder.LITTLE_ENDIAN);
variant.metadata().writeTo(metadataBuffer, 0);
byte[] valueBytes = new byte[variant.value().sizeInBytes()];
ByteBuffer valueBuffer = ByteBuffer.wrap(valueBytes).order(ByteOrder.LITTLE_ENDIAN);
variant.value().writeTo(valueBuffer, 0);
return new VariantVal(valueBytes, metadataBytes);
}
throw new UnsupportedOperationException(
"Unsupported value for VARIANT in StructInternalRow: " + value.getClass());
}
@SuppressWarnings("unchecked")
private <T> GenericArrayData fillArray(
Collection<?> values, Function<Object[], BiConsumer<Integer, T>> makeSetter) {
Object[] array = new Object[values.size()];
BiConsumer<Integer, T> setter = makeSetter.apply(array);
int index = 0;
for (Object value : values) {
if (value == null) {
array[index] = null;
} else {
setter.accept(index, (T) value);
}
index += 1;View on GitHub (pinned to 86d9c8fc54)
Solutions
- Ensure all Iceberg runtime jars (core and spark) are the same version
- Verify the value's class in the message and check which writer produced the data
- Upgrade Iceberg to a version where variant support matches your Spark version
- If reproducible, report as a bug with the value class from the message
Example fix
// before
mvn dependency:tree | grep iceberg # mixed versions
// after
# pin all org.apache.iceberg modules to one version, e.g.
implementation("org.apache.iceberg:iceberg-spark-runtime-4.1_2.13:1.10.0") Defensive patterns
Strategy: try-catch
Type guard
static boolean isIcebergVariant(Object v) { return v instanceof org.apache.iceberg.variants.Variant; } Try / catch
try {
VariantVal vv = row.getVariant(ordinal);
} catch (UnsupportedOperationException e) {
throw new IllegalStateException("Non-Variant value in VARIANT column; check Iceberg version alignment: " + e.getMessage(), e);
} Prevention
- Use one Iceberg version for all modules and writers
- Don't inject custom objects into VARIANT-typed positions
- Reproduce/report with the class name included in the message
When it happens
Trigger: Reading a VARIANT column where the in-memory value is neither an Iceberg Variant nor byte[] (the handled inputs) — typically indicates an internal bug or an unexpected writer format.
Common situations: Mixed Iceberg versions (table written by a different Iceberg runtime producing a different in-memory Variant representation), or custom extensions passing non-standard values through the scan pipeline.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Unsupported value for VARIANT in StructInternalRow: ${value.
- Cannot parse type string: variant is not a primitive type
- Failed to read Variant %s of type %s as int
- Failed to read Variant %s of type %s as long
- Failed to read Variant %s of type %s as double
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/ebbe1d98f633d159.
Report an issue: GitHub.