apache/iceberg · error · UnsupportedOperationException
NOOP timer has no duration
Error message
NOOP timer has no duration
What it means
The NOOP Timer discards all timing data, so it has no total duration to expose. totalDuration() throws UnsupportedOperationException to make accidental metric reads on the disabled timer fail fast instead of silently returning zero. Callers must use a real timer implementation to read durations.
Source
Thrown at api/src/main/java/org/apache/iceberg/metrics/Timer.java:145
Timed NOOP = () -> {};
}
Timer NOOP =
new Timer() {
@Override
public Timed start() {
return Timed.NOOP;
}
@Override
public long count() {
throw new UnsupportedOperationException("NOOP timer has no count");
}
@Override
public Duration totalDuration() {
throw new UnsupportedOperationException("NOOP timer has no duration");
}
@Override
public TimeUnit unit() {
throw new UnsupportedOperationException("NOOP timer has no unit");
}
@Override
public void record(long amount, TimeUnit unit) {}
@Override
public void time(Runnable runnable) {}
@Override
public <T> T timeCallable(Callable<T> callable) throws Exception {
return callable.call();
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Instantiate a real timer (Timer.of / DefaultTimer) rather than Timer.NOOP wherever durations are read.
- Check for the NOOP instance before reading: skip or substitute Duration.ZERO when timer == Timer.NOOP.
- Wrap metric reads in try-catch for UnsupportedOperationException only if NOOP use is unavoidable in legacy paths.
Example fix
// before Duration d = timer.totalDuration(); // after Duration d = (timer == Timer.NOOP) ? Duration.ZERO : timer.totalDuration();
Defensive patterns
Strategy: type-guard
Validate before calling
boolean hasDuration = timer != Timer.NOOP;
Type guard
if (timer == Timer.NOOP) { return Duration.ZERO; } return timer.totalDuration(); Try / catch
try { return timer.totalDuration(); } catch (UnsupportedOperationException e) { return Duration.ZERO; } Prevention
- Only read durations from concrete timer implementations
- Skip NOOP timers when building commit/scan reports
- Keep metrics reads behind a helper that null/NOOP-checks
When it happens
Trigger: Calling Timer.NOOP.totalDuration(), or reading totalDuration() from a timer obtained through a metrics-disabled code path (Timer.Timed.NOOP / NOOP metrics context).
Common situations: Logging scan/commit timing summaries in code that runs with NOOP metrics enabled; tests asserting on durations without a real metrics implementation; dashboards or commit summary producers consuming Timer results unconditionally.
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
- NOOP timer has no count
- NOOP timer has no unit
- NOOP counter has no value
- Count is not supported.
- Counter is not supported.
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/609596c050fab284.
Report an issue: GitHub.