apache/iceberg · error · UnsupportedOperationException

Bucket transform is not supported

Error message

Bucket transform is not supported

What it means

PartitionSpecVisitor's default bucket(sourceName, sourceId, numBuckets) throws UnsupportedOperationException: visitors are expected to override it to handle bucket partition fields. Hitting this default means the spec contained a bucket field the visitor did not implement.

Source

Thrown at api/src/main/java/org/apache/iceberg/transforms/PartitionSpecVisitor.java:41

import org.apache.iceberg.PartitionSpec;
import org.apache.iceberg.Schema;
import org.apache.iceberg.relocated.com.google.common.collect.Lists;

public interface PartitionSpecVisitor<T> {
  default T identity(int fieldId, String sourceName, int sourceId) {
    return identity(sourceName, sourceId);
  }

  default T identity(String sourceName, int sourceId) {
    throw new UnsupportedOperationException("Identity transform is not supported");
  }

  default T bucket(int fieldId, String sourceName, int sourceId, int numBuckets) {
    return bucket(sourceName, sourceId, numBuckets);
  }

  default T bucket(String sourceName, int sourceId, int numBuckets) {
    throw new UnsupportedOperationException("Bucket transform is not supported");
  }

  default T truncate(int fieldId, String sourceName, int sourceId, int width) {
    return truncate(sourceName, sourceId, width);
  }

  default T truncate(String sourceName, int sourceId, int width) {
    throw new UnsupportedOperationException("Truncate transform is not supported");
  }

  default T year(int fieldId, String sourceName, int sourceId) {
    return year(sourceName, sourceId);
  }

  default T year(String sourceName, int sourceId) {
    throw new UnsupportedOperationException("Year transform is not supported");
  }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Override bucket(int fieldId, String sourceName, int sourceId, int numBuckets) (or the legacy overload) in the visitor.
  2. If bucketing is unsupported downstream, detect it up front via spec.fields() and reject with a clear message before visiting.
  3. Add a test visiting a spec with a bucket field to cover the path.

Example fix

// before
new PartitionSpecVisitor<String>() {
  public String identity(String name, int id) { return name; }
}
// after
new PartitionSpecVisitor<String>() {
  public String identity(String name, int id) { return name; }
  @Override
  public String bucket(int fieldId, String sourceName, int sourceId, int numBuckets) {
    return "bucket[" + numBuckets + "](" + sourceName + ")";
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

boolean hasBucket = spec.fields().stream().anyMatch(f -> f.transform().toString().startsWith("bucket"));

Try / catch

try { return PartitionSpecVisitor.visit(spec, visitor); } catch (UnsupportedOperationException e) { throw new IllegalArgumentException("Spec contains unhandled bucket field: " + spec, e); }

Prevention

When it happens

Trigger: Visiting a partition spec that includes a bucket[N] transform with a visitor implementation that does not override bucket(...).

Common situations: Custom spec-to-SQL/translation utilities where the author implemented identity/year/month but not bucket; processing user tables with bucketed partitions through a partial visitor.

Understand the failure class

Background: "NotImplementedError: Subclasses should override this method" / "must be implemented" — abstract method errors explained — this error's family across 40 libraries.

Related errors


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