apache/iceberg · error · UnsupportedOperationException

Transform is not supported: ${transform}

Error message

Transform is not supported: ${transform}

What it means

Thrown by Spark3Util.toIcebergTerm when a Spark Transform in a sort/order expression is not one of the supported kinds (identity, bucket, truncate, years/months/days/hours, etc.). The Spark transform cannot be translated to an Iceberg expression term such as Hilbert or sort expressions.

Source

Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java:430

        case "hour":
        case "hours":
          return org.apache.iceberg.expressions.Expressions.hour(colName);
        case "truncate":
          return org.apache.iceberg.expressions.Expressions.truncate(colName, findWidth(transform));
        case "zorder":
          return new Zorder(
              Stream.of(transform.references())
                  .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
   */

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Rewrite the ordering clause using supported transforms (identity, bucket, truncate, temporal)
  2. Upgrade Iceberg to pick up mappings for newer Spark transforms
  3. Remove unsupported transforms from the DDL and apply equivalent logic at write time

Example fix

// before
CREATE TABLE t (...) USING iceberg ORDER BY (rand());
// after
CREATE TABLE t (...) USING iceberg ORDER BY (id);
Defensive patterns

Strategy: validation

Validate before calling

Set<String> supported = Set.of("identity","bucket","truncate","years","months","days","hours");
if (expr instanceof Transform && !supported.contains(((Transform<?>) expr).name())) {
  throw new IllegalArgumentException("Unsupported transform in ORDER BY: " + ((Transform<?>) expr).name());
}

Try / catch

try {
  term = Spark3Util.toIcebergTerm(expr);
} catch (UnsupportedOperationException e) {
  if (e.getMessage().startsWith("Transform is not supported")) {
    // rewrite the order-by clause with supported transforms
  }
}

Prevention

When it happens

Trigger: CREATE TABLE ... ORDER BY / SORT BY clauses, or catalog code converting Spark sort expressions, containing transforms like 'random' or engine-specific transforms Iceberg has no mapping for.

Common situations: Engine-specific transforms (e.g. custom partition transforms) leaking into Iceberg DDL; version mismatch where Spark added a new built-in transform the Iceberg version predates.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/9f807425d0be0782. Report an issue: GitHub.