apache/iceberg · error
Unsupported time unit: + timestampUnit
Error message
Unsupported time unit: + timestampUnit
What it means
Thrown by the bound Timestamps transform's apply() when the timestamp precision unit itself (the outer switch) is neither MICROS nor NANOS. Iceberg only defines two timestamp precisions — microseconds and nanoseconds — so a Timestamps transform built with any other ChronoUnit as the unit is fundamentally unusable.
Source
Thrown at api/src/main/java/org/apache/iceberg/transforms/Timestamps.java:94
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);
}
}
}
private final ChronoUnit granularity;
private final String name;
private final Apply apply;
Timestamps(ChronoUnit granularity, String name, TimestampUnit timestampUnit) {
this.name = name;
this.granularity = granularity;
this.apply = new Apply(granularity, timestampUnit);
}
/**
* Transforms a value to its corresponding partition value.
*
* @param timestamp a source valueView on GitHub (pinned to 86d9c8fc54)
Solutions
- Construct the transform only with ChronoUnit.MICROS or ChronoUnit.NANOS as the timestamp unit
- Use Transforms.year/month/day/hour factory methods, which always produce a valid precision/granularity pair
- Validate the precision field when deserializing transform specs and reject unknown values early
Example fix
// before new Timestamps(ChronoUnit.SECONDS, ChronoUnit.DAYS); // after new Timestamps(ChronoUnit.MICROS, ChronoUnit.DAYS);
Defensive patterns
Strategy: validation
Validate before calling
if (unit != ChronoUnit.MICROS && unit != ChronoUnit.NANOS) {
throw new IllegalArgumentException("Timestamp unit must be MICROS or NANOS, got: " + unit);
} Try / catch
try { Object v = tsTransform.bind(type).apply(value); } catch (UnsupportedOperationException e) { /* invalid precision: rebuild transform via Transforms.day(...) */ } Prevention
- Only use MICROS or NANOS as timestamp precision — these are the only Iceberg precisions
- Validate precision fields when deserializing transform specs
- Prefer Transforms.* factories over direct Timestamps construction
When it happens
Trigger: Calling apply() on a bound Timestamps transform whose timestampUnit is ChronoUnit.SECOND, MINUTE, or any unit other than MICROS/NANOS — e.g. from a hand-constructed or deserialized transform with a bogus precision.
Common situations: Custom code constructing Timestamps directly instead of via Transforms factories; parsing a partition spec where the timestamp precision field was corrupted or hand-edited.
Related errors
- Unsupported time unit: + granularity
- 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/1f1cf62c3d7c9e32.
Report an issue: GitHub.