apache/iceberg · error · IllegalArgumentException

Counter for type %s is not supported

Error message

Counter for type %s is not supported

What it means

DefaultMetricsContext.counter(name, type) only supports Integer and Long counter types; any other Number subtype (Double, Float, etc.) triggers this IllegalArgumentException with the unsupported type's name. It enforces the metric types Iceberg counters support.

Source

Thrown at api/src/main/java/org/apache/iceberg/metrics/DefaultMetricsContext.java:41

/** A default {@link MetricsContext} implementation that uses native Java counters/timers. */
public class DefaultMetricsContext implements MetricsContext {
  private static final int DEFAULT_HISTOGRAM_RESERVOIR_SIZE = 10_000;

  /**
   * @deprecated will be removed in 2.0.0, use {@link org.apache.iceberg.metrics.Counter} instead.
   */
  @Override
  @Deprecated
  @SuppressWarnings("unchecked")
  public <T extends Number> Counter<T> counter(String name, Class<T> type, Unit unit) {
    if (Integer.class.equals(type)) {
      return (Counter<T>) new DefaultCounter(unit).asIntCounter();
    }

    if (Long.class.equals(type)) {
      return (Counter<T>) new DefaultCounter(unit).asLongCounter();
    }
    throw new IllegalArgumentException(
        String.format("Counter for type %s is not supported", type.getName()));
  }

  @Override
  public Timer timer(String name, TimeUnit unit) {
    return new DefaultTimer(unit);
  }

  @Override
  public org.apache.iceberg.metrics.Counter counter(String name, Unit unit) {
    return new DefaultCounter(unit);
  }

  @Override
  public Histogram histogram(String name) {
    return new FixedReservoirHistogram(DEFAULT_HISTOGRAM_RESERVOIR_SIZE);
  }
}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Use Integer.class or Long.class as the counter type
  2. For non-integer metrics use a Histogram or a different metrics mechanism
  3. Wrap the call and surface a clear configuration error if the type comes from user config

Example fix

// before
Counter<Double> c = metrics.counter("ratio", Double.class, Unit.COUNT);
// after
Counter<Long> c = metrics.counter("ratio", Long.class, Unit.COUNT);
Defensive patterns

Strategy: validation

Validate before calling

if (!Integer.class.equals(type) && !Long.class.equals(type)) { fix; }

Type guard

boolean ok(Class<?> t) { return t == Integer.class || t == Long.class; }

Try / catch

try { ... } catch (IllegalArgumentException e) { fallback to Long counter }

Prevention

When it happens

Trigger: Calling DefaultMetricsContext.counter(name, Double.class, unit) or with any Class<T extends Number> other than Integer.class or Long.class.

Common situations: Developers assuming generic numeric counters are supported; refactoring code from other metrics libraries that allow double counters; copying a counter declaration with a wrong type parameter.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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