apache/iceberg · error · UnsupportedOperationException
Unsupported nested type: ${dataType()}
Error message
Unsupported nested type: ${dataType()} What it means
ColumnVectorWithFilter wraps a delegate ColumnVector and applies a row-id mapping when filtering deleted rows. When lazily constructing child vectors for nested types it supports only two-child structures (e.g. structs with two fields); any other nested data type is rejected with UnsupportedOperationException because filtered child vectors cannot be built for it.
Source
Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/data/vectorized/ColumnVectorWithFilter.java:154
@Override
public ColumnVector getChild(int ordinal) {
if (children == null) {
synchronized (this) {
if (children == null) {
if (dataType() instanceof StructType) {
StructType structType = (StructType) dataType();
this.children = new ColumnVectorWithFilter[structType.length()];
for (int index = 0; index < structType.length(); index++) {
children[index] = new ColumnVectorWithFilter(delegate.getChild(index), rowIdMapping);
}
} else if (dataType() instanceof VariantType) {
this.children =
new ColumnVectorWithFilter[] {
new ColumnVectorWithFilter(delegate.getChild(0), rowIdMapping),
new ColumnVectorWithFilter(delegate.getChild(1), rowIdMapping)
};
} else {
throw new UnsupportedOperationException("Unsupported nested type: " + dataType());
}
}
}
}
return children[ordinal];
}
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Avoid selecting the unsupported nested column in the same query as row-level deletes, or rewrite the deletes as partition-level/whole-file deletes.
- Extend ColumnVectorWithFilter.getChild() to handle the missing nested type (e.g. add a branch for more children or map/list types) if you control the build.
- Disable vectorized reads (spark.sql.iceberg.handle-timestamp-without-timezone / vectorization settings, or set read.vectorization.enabled=false) to fall back to the non-vectorized path.
- Upgrade Iceberg — newer versions broaden nested-type support in the delete-filtered vectorized reader.
Defensive patterns
Strategy: fallback
Try / catch
try {
df = spark.read.format("iceberg").load("table")
} catch (UnsupportedOperationException e) {
if (e.getMessage().contains("Unsupported nested type")) {
spark.conf.set("spark.sql.iceberg.vectorization.enabled", "false");
df = spark.read.format("iceberg").load("table");
} else throw e;
} Prevention
- Test delete-filtered reads against all nested column types your tables use.
- Avoid mixing row-level deletes with wide structs/large nested types in vectorized scans.
- Pin the iceberg-spark-runtime version to your Spark version.
When it happens
Trigger: Reading a column with delete-filtered row mapping whose nested type has children beyond the two supported ones — e.g. a struct with more than 2 fields, or a map/list nested type reached via getChild(ordinal).
Common situations: Row-level delete files applied to tables with wide nested structs; queries selecting deeply nested columns (maps, lists, large structs) while positional/equality deletes are in scope; schema evolution adding a third field to a previously two-field struct read with deletes.
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 nested type: ${dataType()}
- Unsupported nested type: ${dataType}
- Unsupported nested type:
- ${class} does not implement getArray
- Unsupported type: array
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/1ad24f37737a3939.
Report an issue: GitHub.