apache/iceberg · error · UnsupportedOperationException

NOOP timer has no count

Error message

NOOP timer has no count

What it means

The NOOP Timer (returned by Timer.NOOP) deliberately discards all recorded timings and exposes no measurement state. Calling count() on it throws UnsupportedOperationException because there is no accumulated count to report. This is by design: code instrumented with the NOOP timer must never read metrics back from it.

Source

Thrown at api/src/main/java/org/apache/iceberg/metrics/Timer.java:140

    @Override
    default void close() {
      stop();
    }

    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) {}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Use a real Timer implementation (e.g. DefaultTimer via Timer.of / Metrics context) instead of Timer.NOOP when you need to read count().
  2. Guard the read: only call count() when you know the timer is not the NOOP instance (e.g. check timer != Timer.NOOP).
  3. Treat NOOP as write-only instrumentation; derive counts yourself if you need them (count invocations manually).

Example fix

// before
long n = timer.count();
// after
long n = (timer == Timer.NOOP) ? 0L : timer.count();
Defensive patterns

Strategy: type-guard

Validate before calling

boolean readable = timer != Timer.NOOP;

Type guard

if (timer == Timer.NOOP) { return 0L; } return timer.count();

Try / catch

try { return timer.count(); } catch (UnsupportedOperationException e) { return 0L; }

Prevention

When it happens

Trigger: Calling Timer.NOOP.count() directly, or calling count() on a Timer returned from Timer.Timed.NOOP-backed code paths when metrics are disabled (e.g. MetricsUtil/Timers constructed without an implementation).

Common situations: Developers writing generic code that records timings and later reads count() for logging/commit reports while the application runs with the NOOP metrics implementation; unit tests that assert on timer output without wiring a real metrics implementation.

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


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/b55ab568eda79d97. Report an issue: GitHub.