apache/iceberg · error · UnsupportedOperationException

Cannot write using unsupported transforms: %s

Error message

Cannot write using unsupported transforms: %s

What it means

Iceberg writes require every partition field's transform to be understood by the writer. If a target table's partition spec contains an UnknownTransform (a transform the client cannot interpret — typically from a newer spec version or another writer), SparkUtil.validatePartitionTransforms refuses to write, listing the offending transforms.

Source

Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/SparkUtil.java:100

  private SparkUtil() {}

  /**
   * Check whether the partition transforms in a spec can be used to write data.
   *
   * @param spec a PartitionSpec
   * @throws UnsupportedOperationException if the spec contains unknown partition transforms
   */
  public static void validatePartitionTransforms(PartitionSpec spec) {
    if (spec.fields().stream().anyMatch(field -> field.transform() instanceof UnknownTransform)) {
      String unsupported =
          spec.fields().stream()
              .map(PartitionField::transform)
              .filter(transform -> transform instanceof UnknownTransform)
              .map(Transform::toString)
              .collect(Collectors.joining(", "));

      throw new UnsupportedOperationException(
          String.format("Cannot write using unsupported transforms: %s", unsupported));
    }
  }

  /**
   * A modified version of Spark's LookupCatalog.CatalogAndIdentifier.unapply Attempts to find the
   * catalog and identifier a multipart identifier represents
   *
   * @param nameParts Multipart identifier representing a table
   * @return The CatalogPlugin and Identifier for the table
   */
  public static <C, T> Pair<C, T> catalogAndIdentifier(
      List<String> nameParts,
      Function<String, C> catalogProvider,
      BiFunction<String[], String, T> identiferProvider,
      C currentCatalog,
      String[] currentNamespace) {
    Preconditions.checkArgument(

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Upgrade the Iceberg runtime (iceberg-spark) to a version that supports the transforms used in the table's spec
  2. Rewrite the table with a partition spec using supported transforms (identity, year/month/day/hour, bucket, truncate)
  3. Repartition the target table to drop the unknown-transform fields before writing

Example fix

// before: table partitioned by transform 'foo(col)' unknown to this client
df.writeTo("db.tbl").append(); // throws
// after: recreate table with supported spec
PartitionSpec spec = PartitionSpec.builderFor(schema).day("ts").build();
Defensive patterns

Strategy: validation

Validate before calling

boolean hasUnknown = table.spec().fields().stream().anyMatch(f -> f.transform() instanceof UnknownTransform);
if (hasUnknown) throw new IllegalStateException("Target table spec contains transforms unsupported by this client; upgrade Iceberg or repartition");

Try / catch

try { df.writeTo("db.tbl").append(); } catch (UnsupportedOperationException e) { if (e.getMessage().contains("unsupported transforms")) { /* upgrade runtime or repartition table */ } throw e; }

Prevention

When it happens

Trigger: Running a Spark write (e.g. via df.writeTo(...).append()) against an Iceberg table whose partition spec includes fields whose transform resolves to UnknownTransform.

Common situations: Writing to a table created/upgraded by a newer Iceberg version or another engine that supports transforms this client does not; tables created via REST catalog with unrecognized transforms in the spec.

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


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