apache/iceberg · error · ArithmeticException

integer overflow

Error message

integer overflow

What it means

DefaultCounter.asIntCounter() wraps a long-backed counter but must return an Integer; if the underlying count exceeds Integer.MAX_VALUE an ArithmeticException('integer overflow') is thrown rather than silently truncating. This protects correctness of int-typed counters.

Source

Thrown at api/src/main/java/org/apache/iceberg/metrics/DefaultCounter.java:121

    public void increment() {
      increment(1);
    }

    @Override
    public void increment(Integer amount) {
      DefaultCounter.this.increment(amount);
    }

    @Override
    public Optional<Integer> count() {
      return Optional.of(value());
    }

    @Override
    public Integer value() {
      long value = counter.longValue();
      if (value > Integer.MAX_VALUE) {
        throw new ArithmeticException("integer overflow");
      }
      return (int) value;
    }

    @Override
    public MetricsContext.Unit unit() {
      return unit;
    }
  }

  private class AsLongCounter implements MetricsContext.Counter<Long> {

    @Override
    public void increment() {
      DefaultCounter.this.increment();
    }

    @Override

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Use Long.class as the counter type instead of Integer.class for potentially large counts
  2. Switch to counter.longValue() on a long counter instead of int value()
  3. Reset or split counters if int semantics are required
  4. Catch ArithmeticException only if overflow is an acceptable, recoverable condition

Example fix

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

Strategy: validation

Validate before calling

if (counter.longValue() > Integer.MAX_VALUE) { use long; }

Try / catch

try { return intCounter.value(); } catch (ArithmeticException e) { return Integer.MAX_VALUE; }

Prevention

When it happens

Trigger: Incrementing an int counter (obtained via MetricsContext.counter(name, Integer.class, unit)) past 2,147,483,647 and then calling value() (directly or via toString/logging/reporting).

Common situations: Counting large row/record totals with an int counter; aggregating many increments in long-running jobs; metric reporting pipelines that stringify the counter.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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