apache/iceberg · error
Unsupported time unit: + granularity
Error message
Unsupported time unit: + granularity
What it means
Thrown by the bound Timestamps transform's apply() when a ChronoUnit granularity is not one of the supported time granularities (YEARS, MONTHS, DAYS, HOURS) for the microsecond timestamp branch. Iceberg bucket/time transforms only support a fixed set of ChronoUnit granularities, so any other unit (e.g. SECONDS, MINUTES, NANOS granularity on the MICROS branch) cannot be applied. This is a guard against constructing a Timestamps transform with an unsupported granularity.
Source
Thrown at api/src/main/java/org/apache/iceberg/transforms/Timestamps.java:78
@Override
public Integer apply(Long timestamp) {
if (timestamp == null) {
return null;
}
switch (timestampUnit) {
case MICROS:
switch (granularity) {
case YEARS:
return DateTimeUtil.microsToYears(timestamp);
case MONTHS:
return DateTimeUtil.microsToMonths(timestamp);
case DAYS:
return DateTimeUtil.microsToDays(timestamp);
case HOURS:
return DateTimeUtil.microsToHours(timestamp);
default:
throw new UnsupportedOperationException("Unsupported time unit: " + granularity);
}
case NANOS:
switch (granularity) {
case YEARS:
return DateTimeUtil.nanosToYears(timestamp);
case MONTHS:
return DateTimeUtil.nanosToMonths(timestamp);
case DAYS:
return DateTimeUtil.nanosToDays(timestamp);
case HOURS:
return DateTimeUtil.nanosToHours(timestamp);
default:
throw new UnsupportedOperationException("Unsupported time unit: " + granularity);
}
default:
throw new UnsupportedOperationException("Unsupported time unit: " + timestampUnit);
}
}View on GitHub (pinned to 86d9c8fc54)
Solutions
- Use only supported granularities: ChronoUnit.YEARS, MONTHS, DAYS, or HOURS for the transform (e.g. Transforms.day("ts") instead of a raw ChronoUnit)
- Validate any user-supplied granularity against Timestamps.SUPPORTED_GRANULARITIES before constructing the transform
- Catch UnsupportedOperationException and surface a clear message that the granularity must be one of years/months/days/hours
Example fix
// before
Transforms.timestamp(ChronoUnit.SECONDS, "ts");
// after
Transforms.day("ts"); // supported granularities: year, month, day, hour Defensive patterns
Strategy: validation
Validate before calling
if (!Timestamps.SUPPORTED_GRANULARITIES.contains(granularity)) {
throw new IllegalArgumentException("Granularity must be one of " + Timestamps.SUPPORTED_GRANULARITIES + ", got: " + granularity);
} Try / catch
try { Object v = tsTransform.bind(type).apply(value); } catch (UnsupportedOperationException e) { /* granularity unsupported: fall back to day() or rethrow with context */ } Prevention
- Only build timestamp transforms via Transforms.year/month/day/hour factories
- Validate user-supplied granularity strings against Timestamps.SUPPORTED_GRANULARITIES before constructing ChronoUnit-based transforms
- Never pass raw ChronoUnit values like SECONDS or MINUTES into Timestamps
When it happens
Trigger: Calling Timestamps.of(ChronoUnit.MICROS).bind(...).apply() (via the generated function) where the switch granularity falls through to default — i.e. granularity is SECONDS, MINUTES, NANOS, or any non-supported ChronoUnit rather than YEARS/MONTHS/DAYS/HOURS.
Common situations: Programmatically building transforms from user-supplied granularity strings mapped to ChronoUnit without validating against the supported set (ChronoUnit.SECONDS or MINUTES are natural but unsupported choices); deserializing a transform spec from a hand-written partition spec with an unsupported granularity name.
Related errors
- Unsupported time unit: + timestampUnit
- apply(value) is deprecated, use bind(Type).apply(value)
- bind is not implemented
- Unsupported binary type: + value.getClass()
- Cannot truncate type: + type
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/93b5f39d74aebf52.
Report an issue: GitHub.