apache/iceberg · error · UnsupportedOperationException
Struct type is not supported
Error message
Struct type is not supported
What it means
GenericArrowVectorAccessorFactory registers throwing Suppliers for struct and list logical types, so requesting an accessor for a STRUCT column yields a Supplier that throws this UnsupportedOperationException when invoked. The arrow accessor factory simply does not support struct columns in vectorized reads.
Source
Thrown at arrow/src/main/java/org/apache/iceberg/arrow/vectorized/ArrowVectorAccessors.java:44
import org.apache.iceberg.arrow.vectorized.GenericArrowVectorAccessorFactory.DecimalFactory;
import org.apache.iceberg.arrow.vectorized.GenericArrowVectorAccessorFactory.StringFactory;
final class ArrowVectorAccessors {
private static final GenericArrowVectorAccessorFactory<?, String, ?, ?> FACTORY;
static {
FACTORY =
new GenericArrowVectorAccessorFactory<>(
JavaDecimalFactory::new,
JavaStringFactory::new,
throwingSupplier("Struct type is not supported"),
throwingSupplier("List type is not supported"));
}
private static <T> Supplier<T> throwingSupplier(String message) {
return () -> {
throw new UnsupportedOperationException(message);
};
}
private ArrowVectorAccessors() {
throw new UnsupportedOperationException(
ArrowVectorAccessors.class.getName() + " cannot be instantiated.");
}
static ArrowVectorAccessor<?, String, ?, ?> getVectorAccessor(VectorHolder holder) {
return FACTORY.getVectorAccessor(holder);
}
private static final class JavaStringFactory implements StringFactory<String> {
@Override
public Class<String> getGenericClass() {
return String.class;
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Exclude struct columns from the vectorized read projection, or read those columns via the non-vectorized path
- Flatten the struct fields into top-level columns in the query/schema
- Check the Iceberg type of each column before requesting an Arrow accessor and route unsupported types elsewhere
Example fix
// before
ArrowVectorAccessor a = getVectorAccessor(structHolder); // supplier throws
// after
if (structHolder.type().typeId() == TypeID.STRUCT) {
// use row-based reader for this column
} else {
ArrowVectorAccessor a = getVectorAccessor(structHolder);
} Defensive patterns
Strategy: fallback
Validate before calling
if (holder Iceberg type is STRUCT) { routeColumnToRowReader(holder); } Type guard
boolean isStruct(Type t) { return t.typeId() == TypeID.STRUCT; } Try / catch
Supplier<Accessor> s = factory.get(structHolder); try { a = s.get(); } catch (UnsupportedOperationException e) { a = rowReaderAccessor(holder); } Prevention
- Pre-scan the projection schema for structs and split the read into vectorized (primitives) + row (structs) parts
- Flatten structs at query level when vectorized performance is needed
- Document struct limitations of the vectorized path for downstream users
When it happens
Trigger: Reading a table whose schema contains a STRUCT column through the vectorized (Arrow) read path and invoking the accessor factory's struct supplier; passing a VectorHolder backed by a struct type into getVectorAccessor's factory map.
Common situations: Enabling vectorized reads on tables with nested struct fields; listing/reading a nested column set where a struct column sneaks into the batch projection.
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 type: array
- Cannot read files that require applying delete files
- Cannot read without at least one projected column
- Cannot read unsupported column types:
- Format: not supported for batched reads
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/94316c23403c86ce.
Report an issue: GitHub.