apache/beam · error · IllegalArgumentException

ApproximateUnique needs an estimation error between 1%…

Error message

ApproximateUnique needs an estimation error between 1% (0.01) and 50% (0.5).

What it means

ApproximateUnique.Globally requires maximumEstimationError in [0.01, 0.5]; the estimator cannot honor tighter than 1% error nor values above 50%, so out-of-range values throw IllegalArgumentException.

Solutions

  1. Pass the error as a fraction between 0.01 and 0.5, e.g. 0.05 for 5%
  2. If higher precision is needed, use a different transform (e.g. Distinct) that is exact
  3. Normalize percent inputs: error = percent / 100.0 and validate range

Example fix

// before
ApproximateUnique.globally(5) // percent, and > 0.5
// after
ApproximateUnique.globally(0.05)
Defensive patterns

Strategy: validation

Validate before calling

if (error < 0.01 || error > 0.5) throw new IllegalArgumentException("maximumEstimationError must be in [0.01, 0.5]");

Try / catch

try { ApproximateUnique.globally(err); }
catch (IllegalArgumentException e) { /* use 0.05 default or exact Distinct */ }

Prevention

When it happens

Trigger: Constructing Globally (or calling ApproximateUnique.globally(error)) with error < 0.01 or > 0.5, e.g. 0.001 for 'very accurate' counting or 0.9/1.0 by confusion with a confidence level.

Common situations: Confusing estimation error with confidence, passing a percentage (5 for 5%) instead of a fraction, or asking for unreasonably high precision.

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/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/f9f77531bf60d490. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ApproximateUnique.java:195

    public Globally(int sampleSize) {
      if (sampleSize < 16) {
        throw new IllegalArgumentException(
            "ApproximateUnique needs a sampleSize "
                + ">= 16 for an estimation error <= 50%.  "
                + "In general, the estimation "
                + "error is about 2 / sqrt(sampleSize).");
      }

      this.sampleSize = sampleSize;
      this.maximumEstimationError = null;
    }

    /**
     * @see ApproximateUnique#globally(double)
     */
    public Globally(double maximumEstimationError) {
      if (maximumEstimationError < 0.01 || maximumEstimationError > 0.5) {
        throw new IllegalArgumentException(
            "ApproximateUnique needs an " + "estimation error between 1% (0.01) and 50% (0.5).");
      }

      this.sampleSize = sampleSizeFromEstimationError(maximumEstimationError);
      this.maximumEstimationError = maximumEstimationError;
    }

    @Override
    public PCollection<Long> expand(PCollection<T> input) {
      Coder<T> coder = input.getCoder();
      return input.apply(Combine.globally(new ApproximateUniqueCombineFn<>(sampleSize, coder)));
    }

    @Override
    public void populateDisplayData(DisplayData.Builder builder) {
      super.populateDisplayData(builder);
      ApproximateUnique.populateDisplayData(builder, sampleSize, maximumEstimationError);
    }

View on GitHub (pinned to 12126d8942)