{"record":{"id":"30d94fb06f29f576","repo":"apache/iceberg","slug":"cannot-use-column-s-of-type-s-in-zordering-the","errorCode":null,"errorMessage":"Cannot use column %s of type %s in ZOrdering, the type is unsupported","messagePattern":"Cannot use column (.+?) of type (.+?) in ZOrdering, the type is unsupported","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/actions/SparkZOrderUDF.java","lineNumber":343,"sourceCode":"      return longToOrderedBytesUDF().apply(column);\n    } else if (type instanceof FloatType) {\n      return floatToOrderedBytesUDF().apply(column);\n    } else if (type instanceof DoubleType) {\n      return doubleToOrderedBytesUDF().apply(column);\n    } else if (type instanceof StringType) {\n      return stringToOrderedBytesUDF().apply(column);\n    } else if (type instanceof BinaryType) {\n      return bytesTruncateUDF().apply(column);\n    } else if (type instanceof BooleanType) {\n      return booleanToOrderedBytesUDF().apply(column);\n    } else if (type instanceof TimestampType) {\n      return longToOrderedBytesUDF().apply(column.cast(DataTypes.LongType));\n    } else if (type instanceof TimestampNTZType) {\n      return timestampNtzToOrderedBytesUDF().apply(column);\n    } else if (type instanceof DateType) {\n      return longToOrderedBytesUDF().apply(column.cast(DataTypes.LongType));\n    } else {\n      throw new IllegalArgumentException(\n          String.format(\n              \"Cannot use column %s of type %s in ZOrdering, the type is unsupported\",\n              column, type));\n    }\n  }\n\n  private void increaseOutputSize(int bytes) {\n    totalOutputBytes = Math.min(totalOutputBytes + bytes, maxOutputSize);\n  }\n}\n","sourceCodeStart":325,"sourceCodeEnd":354,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/actions/SparkZOrderUDF.java#L325-L354","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nactions.rewriteDataFiles(table).option(\"strategy\", \"zorder\").zOrder(\"nested_struct_col\").execute();\n// after\n// Z-order on a supported primitive extracted from the data instead\nactions.rewriteDataFiles(table).option(\"strategy\", \"zorder\").zOrder(\"nested_struct_col.id\").execute();","handlingStrategy":"validation","validationCode":"// Before zOrdering, check each column's Spark type\nList<String> unsupported = columns.stream()\n    .filter(c -> {\n      org.apache.spark.sql.types.DataType t = table.schema().findField(c).asStructField().type();\n      return t instanceof MapType || t instanceof ArrayType || t instanceof StructType;\n    })\n    .collect(Collectors.toList());\nif (!unsupported.isEmpty()) throw new IllegalArgumentException(\"Unsupported ZOrder columns: \" + unsupported);","typeGuard":"private static boolean isZOrderSupported(org.apache.spark.sql.types.DataType t) {\n  return t instanceof org.apache.spark.sql.types.NumericType\n      || t instanceof org.apache.spark.sql.types.StringType\n      || t instanceof org.apache.spark.sql.types.BooleanType\n      || t instanceof org.apache.spark.sql.types.DateType\n      || t instanceof org.apache.spark.sql.types.TimestampType\n      || t instanceof org.apache.spark.sql.types.TimestampNTZType\n      || t instanceof org.apache.spark.sql.types.BinaryType;\n}","tryCatchPattern":null,"preventionTips":["Only Z-order on primitive-typed columns","Check schema() before configuring zOrderCols","Extract primitives from struct/map columns first"],"tags":["spark","zorder","unsupported-type","data-compaction"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}