apache/iceberg · error · UnsupportedOperationException
Unsupported element type for Array or Map: %s
Error message
Unsupported element type for Array or Map: %s
What it means
VariantRowDataWrapper.elementValue converts a Variant element (inside an ARRAY or MAP) into Flink data according to the declared Flink LogicalType. The switch handles primitives, decimal, string, timestamps, binary, arrays, maps and rows; any other LogicalTypeRoot (e.g. DATE, TIME, INTERVAL, MULTISET) is unsupported and throws UnsupportedOperationException with the element type formatted in the message.
Source
Thrown at flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/data/VariantRowDataWrapper.java:208
case BOOLEAN -> variant.getBoolean();
case TINYINT -> variant.getByte();
case SMALLINT -> variant.getShort();
case INTEGER -> intValue(variant);
case BIGINT -> longValue(variant);
case FLOAT -> variant.getFloat();
case DOUBLE -> doubleValue(variant);
case DECIMAL -> decimalDataValue(variant, (DecimalType) elementType);
case CHAR, VARCHAR -> StringData.fromString(variant.getString());
case TIMESTAMP_WITHOUT_TIME_ZONE ->
timestampValue(variant, ((TimestampType) elementType).getPrecision());
case TIMESTAMP_WITH_LOCAL_TIME_ZONE ->
timestampValue(variant, ((LocalZonedTimestampType) elementType).getPrecision());
case BINARY, VARBINARY -> variant.getBytes();
case ARRAY -> arrayDataValue(variant, ((ArrayType) elementType).getElementType());
case MAP -> mapDataValue(variant, (MapType) elementType);
case ROW -> new VariantRowDataWrapper((RowType) elementType).wrap(variant);
default ->
throw new UnsupportedOperationException(
String.format("Unsupported element type for Array or Map: %s", elementType));
};
}
private static MapData mapDataValue(Variant variant, MapType mapType) {
if (isNull(variant)) {
return null;
}
LogicalType keyType = mapType.getKeyType();
LogicalType valueType = mapType.getValueType();
Preconditions.checkArgument(
keyType instanceof VarCharType,
"Only Map with STRING key type is supported in Variant to RowData conversion");
Map<Object, Object> mapData = Maps.newHashMap();
List<String> keys = BinaryVariantAccessorUtils.fieldNames(variant);View on GitHub (pinned to 86d9c8fc54)
Solutions
- Adjust the declared RowType so array element / map value types are among the supported set (primitives, decimal, string, timestamp, binary, array, map, row).
- Convert unsupported element types (e.g. DATE, TIME) upstream — e.g. read them as string or as their epoch representations.
- Upgrade iceberg-flink if a newer version added support for the logical type named in the message.
- Filter out or cast the offending nested field in the query before it reaches the variant wrapper.
Example fix
// before // rowType declares element type DATE() for a variant array RowData row = new VariantRowDataWrapper(rowType).wrap(variant); ArrayData arr = row.getArray(pos); // throws // after // declare the element as VARCHAR and convert at the sink RowType fixedType = RowType.of(new VarCharType(), ...); RowData row = new VariantRowDataWrapper(fixedType).wrap(variant); StringData dateStr = row.getArray(pos).getString(0); // "2026-09-11"
Defensive patterns
Strategy: validation
Validate before calling
Set<LogicalTypeRoot> supported = Set.of(LogicalTypeRoot.NULL, LogicalTypeRoot.BOOLEAN,
LogicalTypeRoot.TINYINT, LogicalTypeRoot.SMALLINT, LogicalTypeRoot.INTEGER, LogicalTypeRoot.BIGINT,
LogicalTypeRoot.FLOAT, LogicalTypeRoot.DOUBLE, LogicalTypeRoot.DECIMAL, LogicalTypeRoot.CHAR,
LogicalTypeRoot.VARCHAR, LogicalTypeRoot.TIMESTAMP_WITHOUT_TIME_ZONE,
LogicalTypeRoot.TIMESTAMP_WITH_LOCAL_TIME_ZONE, LogicalTypeRoot.BINARY, LogicalTypeRoot.VARBINARY,
LogicalTypeRoot.ARRAY, LogicalTypeRoot.MAP, LogicalTypeRoot.ROW);
LogicalTypeRoot root = elemType.getTypeRoot();
Preconditions.checkArgument(supported.contains(root),
"Element type %s unsupported in Variant array/map", elemType); Type guard
boolean isVariantElementSupported(LogicalType t) {
switch (t.getTypeRoot()) {
case DATE:
case TIME_WITHOUT_TIME_ZONE:
case INTERVAL_YEAR_MONTH:
case INTERVAL_DAY_TIME:
return false;
default:
return true;
}
} Try / catch
try {
ArrayData arr = wrapper.getArray(pos);
} catch (UnsupportedOperationException e) {
if (e.getMessage().startsWith("Unsupported element type for Array or Map:")) {
log.error("Variant collection element type not supported: {}", e.getMessage());
throw new UnsupportedColumnTypeException(e);
}
throw e;
} Prevention
- Declare only supported LogicalTypes for variant array elements and map values in your RowType.
- Convert DATE/TIME-typed variant elements to VARCHAR or INT representations upstream.
When it happens
Trigger: Reading an Iceberg variant column through VariantRowDataWrapper where an array element type or map value type is declared as a Flink type outside the supported set — e.g. a variant array of DATE or TIME values, or a map with non-string key routed to elementValue, in VariantRowDataWrapper.getArray/getMap.
Common situations: Declaring a Flink schema for a variant column whose nested array/map element types use DATE, TIME, or other logical types the wrapper doesn't map; schema evolution adding new element types to variant collections; engine version differences in which Flink types a variant can surface as.
Related errors
- Avro format doesn't support non-string as key type of map. T
- Not a supported type: ${flinkVariant.getClass()}
- Unsupported element type for Array or Map: %s
- Not a supported type: " + flinkVariant.getClass()
- Unsupported type: variant
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/0dd95b98aed1fc43.
Report an issue: GitHub.