apache/iceberg · error · IllegalArgumentException
Cannot bucket by type:
Error message
Cannot bucket by type:
What it means
Bucket.get(Type, int) only supports bucketing source types that Iceberg defines bucket transforms for (int, long, date, time, timestamp, timestamptz, string, uuid, decimal, ByteBuffer variants, timestamp nanos). Requesting a bucket function for any other type hits the default branch and throws IllegalArgumentException. This is a programming/spec error: the requested type is not bucketable.
Source
Thrown at api/src/main/java/org/apache/iceberg/transforms/Bucket.java:78
case INTEGER:
return (B) new BucketInteger(numBuckets);
case TIME:
case TIMESTAMP:
case LONG:
return (B) new BucketLong(numBuckets);
case DECIMAL:
return (B) new BucketDecimal(numBuckets);
case STRING:
return (B) new BucketString(numBuckets);
case FIXED:
case BINARY:
return (B) new BucketByteBuffer(numBuckets);
case TIMESTAMP_NANO:
return (B) new BucketTimestampNano(numBuckets);
case UUID:
return (B) new BucketUUID(numBuckets);
default:
throw new IllegalArgumentException("Cannot bucket by type: " + type);
}
}
private final int numBuckets;
private Bucket(int numBuckets) {
this.numBuckets = numBuckets;
}
public Integer numBuckets() {
return numBuckets;
}
@Override
public SerializableFunction<T, Integer> bind(Type type) {
Preconditions.checkArgument(canTransform(type), "Cannot bucket by type: %s", type);
return get(type, numBuckets);
}View on GitHub (pinned to 86d9c8fc54)
Solutions
- Check Bucket.get(Type).contains(type) (or type(type).isBucketType()) before calling get/bind.
- Fix the source column type to a bucketable type or choose a supported transform (truncate, identity) for that type.
- If handling an unknown type is expected, catch IllegalArgumentException and surface a clear spec-validation error.
Example fix
// before Function<Integer, Integer> fn = Bucket.get(type, numBuckets).bind(type); // after Preconditions.checkArgument(Bucket.get(type).contains(type), "Type %s is not bucketable", type); Function<Integer, Integer> fn = Bucket.get(type, numBuckets).bind(type);
Defensive patterns
Strategy: validation
Validate before calling
if (!Bucket.get(type).contains(type)) { throw new IllegalArgumentException("Cannot bucket by type: " + type); } Type guard
boolean isBucketable(Type t) { return Bucket.get(t).contains(t); } Try / catch
try { return Bucket.get(type, numBuckets).bind(type); } catch (IllegalArgumentException e) { throw new SchemaParseException("Unsupported bucket source type: " + type, e); } Prevention
- Validate column types against Bucket.get(type) before building bucket transforms
- Use TransformUtil/Transforms factory helpers that check canTransform
- Keep spec parsing tests covering every bucketable type
When it happens
Trigger: Calling Bucket.get(type, numBuckets) with an unsupported Type (e.g. boolean, map, list, struct), or binding a bucket transform to an incompatible type via Bucket.bind(type) when canTransform was bypassed.
Common situations: Constructing partition specs programmatically with a bucket transform on a non-bucketable column type; custom catalog/visitor code building transforms from parsed specs with wrong type mapping; version changes adding new bucketable types (e.g. TIMESTAMP_NANO) not handled by downstream code.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- hash(value) is not supported on the base Bucket class
- Unsupported time unit:
- Identity transform is not supported
- Bucket transform is not supported
- Truncate transform is not supported
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/73ce3dab77614df1.
Report an issue: GitHub.