apache/iceberg · error · IllegalArgumentException
Cannot use column %s of type %s in ZOrdering, the type is un
Error message
Cannot use column %s of type %s in ZOrdering, the type is unsupported
What it means
SparkZOrderUDF.sortedLexicographically builds a Spark expression that converts a column's values to lexicographically ordered bytes for Z-Order sorting. It only supports a fixed set of Spark types (numeric, string, binary, date, timestamp, timestamp_ntz, boolean, etc.); anything else reaches the final else branch. This IllegalArgumentException tells you the column's Spark type cannot be Z-ordered by this UDF.
Source
Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/actions/SparkZOrderUDF.java:343
return longToOrderedBytesUDF().apply(column);
} else if (type instanceof FloatType) {
return floatToOrderedBytesUDF().apply(column);
} else if (type instanceof DoubleType) {
return doubleToOrderedBytesUDF().apply(column);
} else if (type instanceof StringType) {
return stringToOrderedBytesUDF().apply(column);
} else if (type instanceof BinaryType) {
return bytesTruncateUDF().apply(column);
} else if (type instanceof BooleanType) {
return booleanToOrderedBytesUDF().apply(column);
} else if (type instanceof TimestampType) {
return longToOrderedBytesUDF().apply(column.cast(DataTypes.LongType));
} else if (type instanceof TimestampNTZType) {
return timestampNtzToOrderedBytesUDF().apply(column);
} else if (type instanceof DateType) {
return longToOrderedBytesUDF().apply(column.cast(DataTypes.LongType));
} else {
throw new IllegalArgumentException(
String.format(
"Cannot use column %s of type %s in ZOrdering, the type is unsupported",
column, type));
}
}
private void increaseOutputSize(int bytes) {
totalOutputBytes = Math.min(totalOutputBytes + bytes, maxOutputSize);
}
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Choose sort columns with supported primitive types (int/long/double/string/boolean/date/timestamp/timestamp_ntz/binary/decimal).
- Extract a supported primitive from the complex column before Z-ordering, e.g. cast or select a struct field via a derived column.
- If the type is a reasonable candidate for support, upgrade Iceberg to a newer patch/release where more Spark types are handled.
- Fall back to a regular sort (sort strategy with sort_order) for the unsupported column instead of zOrderCols.
Example fix
// before
actions.rewriteDataFiles(table).option("strategy", "zorder").zOrder("nested_struct_col").execute();
// after
// Z-order on a supported primitive extracted from the data instead
actions.rewriteDataFiles(table).option("strategy", "zorder").zOrder("nested_struct_col.id").execute(); Defensive patterns
Strategy: validation
Validate before calling
// Before zOrdering, check each column's Spark type
List<String> unsupported = columns.stream()
.filter(c -> {
org.apache.spark.sql.types.DataType t = table.schema().findField(c).asStructField().type();
return t instanceof MapType || t instanceof ArrayType || t instanceof StructType;
})
.collect(Collectors.toList());
if (!unsupported.isEmpty()) throw new IllegalArgumentException("Unsupported ZOrder columns: " + unsupported); Type guard
private static boolean isZOrderSupported(org.apache.spark.sql.types.DataType t) {
return t instanceof org.apache.spark.sql.types.NumericType
|| t instanceof org.apache.spark.sql.types.StringType
|| t instanceof org.apache.spark.sql.types.BooleanType
|| t instanceof org.apache.spark.sql.types.DateType
|| t instanceof org.apache.spark.sql.types.TimestampType
|| t instanceof org.apache.spark.sql.types.TimestampNTZType
|| t instanceof org.apache.spark.sql.types.BinaryType;
} Prevention
- Only Z-order on primitive-typed columns
- Check schema() before configuring zOrderCols
- Extract primitives from struct/map columns first
When it happens
Trigger: Calling SparkActions.get().zOrderTable(...) (rewrite_data_files with zIndex strategy) on a table whose sort columns include a Spark type with no ordered-bytes UDF, e.g. nested STRUCT, ARRAY, MAP, or an exotic type not covered by the if/else chain in sortedLexicographically.
Common situations: Users pass a struct/map/array column or an unhandled logical type (e.g. interval) to the z-order Columns option; also seen when clustering on columns of newly introduced Spark types that the v3.5 action code does not yet map.
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
- Cannot use column %s of type %s in ZOrdering, the type is un
- Cannot use column %s of type %s in ZOrdering, the type is un
- Cannot convert type to SQL: %s
- Unsupported logical type:
- Unsupported type:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/30d94fb06f29f576.
Report an issue: GitHub.