apache/beam · error · IllegalArgumentException

Compression factor should be greater than 0.

Error message

Compression factor should be greater than 0.

What it means

TDigestQuantilesFn.create(compression) validates that the compression factor is strictly greater than 0 before constructing the function; the compression factor bounds centroid/digest sizes and is meaningless or harmful at zero or below. A non-positive value triggers this IllegalArgumentException immediately at construction time (fail-fast, not at pipeline runtime).

Solutions

  1. Pass a positive compression value; the T-Digest reference default is 100.
  2. Validate config-derived values before calling create(): check compression > 0 and fail with a clear message.
  3. If compression is optional, substitute a sensible default (e.g. 100) when unset instead of 0.
  4. Clamp or reject negative values at configuration load time rather than at transform construction.

Example fix

// before
TDigestQuantilesFn fn = TDigestQuantilesFn.create(compression); // compression = 0 from config

// after
if (compression <= 0) {
  compression = 100.0; // T-Digest default
}
TDigestQuantilesFn fn = TDigestQuantilesFn.create(compression);
Defensive patterns

Strategy: validation

Validate before calling

if (compression == null || Double.isNaN(compression) || compression <= 0) {
  throw new IllegalArgumentException("compression must be > 0, got: " + compression);
}

Type guard

boolean isValidCompression(double c) { return !Double.isNaN(c) && c > 0.0; }

Try / catch

try {
  TDigestQuantilesFn fn = TDigestQuantilesFn.create(compression);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("Compression factor")) {
    LOG.warn("Invalid compression {}, falling back to default 100", compression);
    compression = 100.0;
    fn = TDigestQuantilesFn.create(compression);
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling TDigestQuantilesFn.create(0), create(-0.5), or passing a computed/negative variable (e.g. from config parsing) as compression to Sketches.quantiles(...).create(...).

Common situations: Config values read as 0 when unset (double default), sign errors when computing compression from other parameters, unit confusion (e.g. passing a percentile 0-1 where a compression >0 is expected and getting 0).

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

Appendix: source

Thrown at sdks/java/extensions/sketching/src/main/java/org/apache/beam/sdk/extensions/sketching/TDigestQuantiles.java:265

    private TDigestQuantilesFn(double compression) {
      this.compression = compression;
    }

    /**
     * Returns {@link TDigestQuantilesFn} combiner with the given compression factor.
     *
     * <p>Keep in mind that a compression factor {@code cf} of c guarantees a relative error less
     * than 3/c at mid quantiles. <br>
     * The accuracy will always be significantly less than 1% at extreme quantiles.
     *
     * @param compression the bound value for centroid and digest sizes.
     */
    public static TDigestQuantilesFn create(double compression) {
      if (compression > 0) {
        return new TDigestQuantilesFn(compression);
      }
      throw new IllegalArgumentException("Compression factor should be greater than 0.");
    }

    @Override
    public MergingDigest createAccumulator() {
      return new MergingDigest(compression);
    }

    @Override
    public MergingDigest addInput(MergingDigest accum, Double value) {
      accum.add(value);
      return accum;
    }

    /** Output the whole structure so it can be queried, reused or stored easily. */
    @Override
    public MergingDigest extractOutput(MergingDigest accum) {
      return accum;
    }

View on GitHub (pinned to 12126d8942)