apache/iceberg · error · java.lang.UnsupportedOperationException
Cannot convert unknown expression
Error message
Cannot convert unknown expression: <expr>
What it means
toIcebergTerm handles two kinds of Spark expression trees: transforms and NamedReference (plain column references). Anything else at the top level cannot be mapped to an Iceberg Term and throws UnsupportedOperationException with the expression's toString.
Solutions
- Use plain column references or supported transforms in the DDL clause
- Pre-compute complex expressions into a materialized column, then reference that column
- Validate the expression is a Transform or NamedReference before calling toIcebergTerm
Example fix
// before SORTED BY (upper(name)); // after SORTED BY (name);
Defensive patterns
Strategy: type-guard
Validate before calling
if (!(expr instanceof Transform) && !(expr instanceof NamedReference)) {
throw new IllegalArgumentException("Only columns and transforms are supported: " + expr);
} Type guard
static boolean isConvertibleTerm(Expression expr) {
return expr instanceof Transform || expr instanceof NamedReference;
} Try / catch
try {
Term term = Spark3Util.toIcebergTerm(expr);
} catch (UnsupportedOperationException e) {
// surface a clear DDL error telling users to use plain columns or transforms
} Prevention
- Only accept bare columns or supported transforms in DDL clauses that map to Iceberg terms
- Pre-compute complex expressions into columns
- Reject arbitrary expressions in DDL validation
When it happens
Trigger: Passing a complex Spark expression (e.g. a predicate or function call, not a bare column or transform) into Spark3Util.toIcebergTerm.
Common situations: DDL constructs like ORDER/CLUSTER BY with computed expressions rather than plain columns; custom extensions emitting arbitrary expressions where only references/transforms are expected.
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
- Altering a view is not supported by catalog:
- Altering a view is not supported by catalog
- Altering a view is not supported by catalog
- Altering a view is not supported by catalog
- Altering a view is not supported by catalog: catalogName
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/fd53637d5959abda.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java:421
.map(ref -> DOT.join(ref.fieldNames()))
.map(org.apache.iceberg.expressions.Expressions::ref)
.collect(Collectors.toList()));
case "hilbert":
return new Hilbert(
Stream.of(transform.references())
.map(ref -> DOT.join(ref.fieldNames()))
.map(org.apache.iceberg.expressions.Expressions::ref)
.collect(Collectors.toList()));
default:
throw new UnsupportedOperationException("Transform is not supported: " + transform);
}
} else if (expr instanceof NamedReference) {
NamedReference ref = (NamedReference) expr;
return org.apache.iceberg.expressions.Expressions.ref(DOT.join(ref.fieldNames()));
} else {
throw new UnsupportedOperationException("Cannot convert unknown expression: " + expr);
}
}
/**
* Converts Spark transforms into a {@link PartitionSpec}.
*
* @param schema the table schema
* @param partitioning Spark Transforms
* @return a PartitionSpec
*/
public static PartitionSpec toPartitionSpec(Schema schema, Transform[] partitioning) {
if (partitioning == null || partitioning.length == 0) {
return PartitionSpec.unpartitioned();
}
PartitionSpec.Builder builder = PartitionSpec.builderFor(schema);
for (Transform transform : partitioning) {
Preconditions.checkArgument(View on GitHub (pinned to 86d9c8fc54)