apache/iceberg · error · UnsupportedOperationException

Count is not supported.

Error message

Count is not supported.

What it means

Counter.value() is a default method on the MetricsContext.Counter interface that throws UnsupportedOperationException('Count is not supported.') — implementations are expected to override it. A context that does not support counters (or a custom Counter implementation that skips it) leaves this stub in place, so reading the count fails.

Source

Thrown at api/src/main/java/org/apache/iceberg/metrics/MetricsContext.java:92

    /**
     * Reporting count is optional if the counter is reporting externally.
     *
     * @return current count if available
     * @deprecated Use {@link Counter#value()}
     */
    @Deprecated
    default Optional<T> count() {
      return Optional.empty();
    }

    /**
     * Reports the current count.
     *
     * @return The current count
     */
    default T value() {
      throw new UnsupportedOperationException("Count is not supported.");
    }

    /**
     * The unit of the counter.
     *
     * @return The unit of the counter.
     */
    default Unit unit() {
      return Unit.UNDEFINED;
    }
  }

  /**
   * Get a named counter of a specific type. Metric implementations may impose restrictions on what
   * types are supported for specific counters.
   *
   * @param name name of the metric
   * @param type numeric type of the counter value

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Override value() in your Counter implementation to return the real count
  2. Use DefaultMetricsContext/DefaultCounter which implement value()
  3. Don't read value() from counters obtained via unsupported contexts; use toString or count() where appropriate
  4. Check the MetricsContext implementation actually records before consuming values

Example fix

// before
class MyCounter implements Counter<Long> { /* value() not overridden */ }
// after
class MyCounter implements Counter<Long> {
  @Override
  public Long value() { return count.get(); }
}
Defensive patterns

Strategy: try-catch

Try / catch

try { counter.value(); } catch (UnsupportedOperationException e) { skip; }

Prevention

When it happens

Trigger: Calling value() on a Counter returned by a MetricsContext that did not override value(), e.g. a custom MetricsContext extending the interface without implementing counters, or the deprecated counter() default stubs on the interface.

Common situations: Custom MetricsContext implementations missing value() overrides; code reading counter values from contexts that were never meant to record (unsupported default methods); upgrade paths where a new interface method wasn't implemented.

Related errors


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