apache/iceberg · error · UnsupportedOperationException
Expected number of buckets to be tinyint, shortint or int
Error message
Expected number of buckets to be tinyint, shortint or int
What it means
Iceberg's bucket table function (days/hours style transform exposed as a Spark function) binds its arguments at planning time. The second argument's first input field is the bucket count, which must be one of ByteType, ShortType, or IntegerType so it can be widened to an int internally. Spark's bind() throws UnsupportedOperationException when the numBuckets field has any other type (e.g. long, string, decimal, null).
Solutions
- Cast the bucket width expression to INT: bucket(cast(width AS INT), col) — Spark literal 1024 is already INT.
- If the width comes from a BIGINT column, wrap it: bucket(int(widthCol), col).
- Check the actual type of the first argument with typeof() in Spark SQL to confirm the mismatch.
- If passing a NULL, cast it explicitly: cast(NULL AS INT).
Example fix
// before SELECT iceberg.bucket(1024L, id) FROM t; // after SELECT iceberg.bucket(1024, id) FROM t; -- INT literal -- or SELECT iceberg.bucket(CAST(width_col AS INT), id) FROM t;
Defensive patterns
Strategy: validation
Validate before calling
val widthType = widthExpr.dataType require(widthType == ByteType || widthType == ShortType || widthType == IntegerType, s"bucket width must be tinyint/short/int, got $widthType")
Type guard
def isSupportedWidth(t: DataType): Boolean = t == ByteType || t == ShortType || t == IntegerType
Prevention
- Use plain integer literals for bucket widths (1024, 256), never L-suffixed or BIGINT-typed values
- Cast any width derived from a column or config string to INT before calling iceberg.bucket
When it happens
Trigger: Calling iceberg.bucket(width, col) where the width expression is not a tinyint/short/int literal or column — e.g. bucket(1024L, id), bucket(cast('10' as string), id), or bucket(someBigIntCol, id).
Common situations: Passing the bucket width as a BIGINT constant from another column or computed expression; typing the width in SQL as a plain number that Spark parses to BIGINT (literals default to INT only below certain sizes); schema evolution changing the width column type.
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
- Expected truncation width to be tinyint, shortint or int
- 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
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/e202a8e8260ed73f.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/functions/BucketFunction.java:79
private static final int NUM_BUCKETS_ORDINAL = 0;
private static final int VALUE_ORDINAL = 1;
private static final Set<DataType> SUPPORTED_NUM_BUCKETS_TYPES =
ImmutableSet.of(DataTypes.ByteType, DataTypes.ShortType, DataTypes.IntegerType);
@Override
@SuppressWarnings("checkstyle:CyclomaticComplexity")
public BoundFunction bind(StructType inputType) {
if (inputType.size() != 2) {
throw new UnsupportedOperationException(
"Wrong number of inputs (expected numBuckets and value)");
}
StructField numBucketsField = inputType.fields()[NUM_BUCKETS_ORDINAL];
StructField valueField = inputType.fields()[VALUE_ORDINAL];
if (!SUPPORTED_NUM_BUCKETS_TYPES.contains(numBucketsField.dataType())) {
throw new UnsupportedOperationException(
"Expected number of buckets to be tinyint, shortint or int");
}
DataType type = valueField.dataType();
if (type instanceof DateType) {
return new BucketInt(type);
} else if (type instanceof ByteType
|| type instanceof ShortType
|| type instanceof IntegerType) {
return new BucketInt(DataTypes.IntegerType);
} else if (type instanceof LongType) {
return new BucketLong(type);
} else if (type instanceof TimestampType) {
return new BucketLong(type);
} else if (type instanceof TimestampNTZType) {
return new BucketLong(type);
} else if (type instanceof DecimalType) {
return new BucketDecimal(type);View on GitHub (pinned to 86d9c8fc54)