apache/iceberg · error · UnsupportedOperationException
Unsupported array element type
Error message
Unsupported array element type: ${elementType} What it means
When StructInternalRow converts a nested collection (array) into Spark's ArrayData, it switches over the Iceberg element type and throws UnsupportedOperationException for element types it cannot encode. The default branch fires whenever an array's elementType falls outside the explicitly handled set (primitives, strings, decimal, date/timestamp, structs, maps, variants, etc.).
Solutions
- Upgrade the iceberg-spark-runtime jar to a version whose StructInternalRow supports the element type named in the message.
- Check which Iceberg version wrote the table and ensure reader/writer version compatibility.
- If the type cannot be supported, rewrite the column as a supported type (e.g. cast array elements) before reading.
- Reproduce with the exact type name printed in the message and check Iceberg release notes for that type's Spark support.
Example fix
// before (cluster classpath) iceberg-spark-runtime-4.0_2.13-1.5.0.jar // after iceberg-spark-runtime-4.0_2.13-1.7.0.jar // supports the array element type
Defensive patterns
Strategy: validation
Validate before calling
Type elem = schema.findField(name).type().asListType().elementType();
if (!isSupportedElementType(elem)) {
throw new UnsupportedOperationException("Upgrade Iceberg runtime to read array of " + elem);
} Type guard
static boolean isSupportedElementType(Type t) {
switch (t.typeId()) {
case BOOLEAN: case INTEGER: case LONG: case FLOAT: case DOUBLE:
case DATE: case TIME: case TIMESTAMP: case STRING: case UUID:
case FIXED: case BINARY: case DECIMAL: case STRUCT: case LIST:
case MAP: case VARIANT:
return true;
default:
return false;
}
} Try / catch
try {
Dataset<Row> df = spark.read().format("iceberg").load(tableIdent);
} catch (UnsupportedOperationException e) {
if (e.getMessage().startsWith("Unsupported array element type")) {
// upgrade runtime jar or rewrite column as a supported type
} else throw e;
} Prevention
- Keep the Iceberg Spark runtime version >= the version that wrote the table.
- Test reads of all nested types after table rewrites or format migrations.
- Avoid experimental/custom types in shared production tables.
When it happens
Trigger: Reading an Iceberg list column whose element type is not handled by collectionToArrayData — typically types added in newer Iceberg spec/versions than the installed Spark integration supports, reached during Spark reads via getArray(ordinal).
Common situations: Reading tables written by a newer Iceberg writer than the reader runtime; a stale iceberg-spark-runtime jar on the cluster classpath; schema evolution introducing a type variant unsupported by the installed Spark 4.0 module version.
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
- Unsupported array element type:
- Unsupported array element type: " + elementType
- Cannot convert type to SQL
- Cannot convert unsupported type to Spark
- Cannot use column of type in ZOrdering, the type is…
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/c229510c889821f9.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java:356
return fillArray(
values,
array ->
(BiConsumer<Integer, Collection<?>>)
(pos, list) ->
array[pos] =
collectionToArrayData(elementType.asListType().elementType(), list));
case MAP:
return fillArray(
values,
array ->
(BiConsumer<Integer, Map<?, ?>>)
(pos, map) -> array[pos] = mapToMapData(elementType.asMapType(), map));
case VARIANT:
return fillArray(
values,
array -> (BiConsumer<Integer, Object>) (pos, v) -> array[pos] = toVariantVal(v));
default:
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(View on GitHub (pinned to 86d9c8fc54)