apache/beam · error · IllegalArgumentException

getPositionForFractionConsumed is not applicable to an…

Error message

getPositionForFractionConsumed is not applicable to an unbounded range: 

What it means

OffsetRangeTracker.getPositionForFractionConsumed computes a position corresponding to a fraction of a bounded range [start, stop). Fraction-based progress is meaningless for an unbounded range (stop == Long.MAX_VALUE / OFFSET_INFINITY), so the method throws IllegalArgumentException in that case.

Solutions

  1. Check tracker.getStopOffset() != Long.MAX_VALUE before calling getPositionForFractionConsumed.
  2. Use getFractionConsumed() on the tracker instead, which handles unbounded ranges.
  3. Restrict fraction-based progress reporting to bounded (batch) sources.
  4. For unbounded sources, estimate progress from records processed or watermark rather than range fraction.

Example fix

// before
long pos = tracker.getPositionForFractionConsumed(0.5);
// after
if (tracker.getStopOffset() != Long.MAX_VALUE) {
  long pos = tracker.getPositionForFractionConsumed(0.5);
} else {
  Double frac = tracker.getFractionConsumed(); // handles unbounded
}
Defensive patterns

Strategy: validation

Validate before calling

if (tracker.getStopOffset() != Long.MAX_VALUE) { long pos = tracker.getPositionForFractionConsumed(f); }

Type guard

boolean isBounded = tracker.getStopOffset() != Long.MAX_VALUE;

Try / catch

try { pos = tracker.getPositionForFractionConsumed(f); } catch (IllegalArgumentException e) { pos = -1; /* unbounded */ }

Prevention

When it happens

Trigger: Calling getPositionForFractionConsumed(fraction) on a tracker whose range was created with OFFSET_INFINITY (e.g. OffsetRangeTracker(Long.MAX_VALUE) or an unbounded IO like Pub/Sub-backed sources).

Common situations: Streaming pipelines or tests (e.g. testEverythingWithUnboundedRange) that query fractional progress on unbounded sources, or generic monitoring code that assumes all sources are bounded.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/61fb1dc59f7ebb96. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/io/range/OffsetRangeTracker.java:169

    }
    if (splitOffset < startOffset || splitOffset >= stopOffset) {
      LOG.debug(
          "Refusing to split {} at {}: proposed split position out of range", this, splitOffset);
      return false;
    }
    LOG.debug("Agreeing to split {} at {}", this, splitOffset);
    this.stopOffset = splitOffset;
    return true;
  }

  /**
   * Returns a position {@code P} such that the range {@code [start, P)} represents approximately
   * the given fraction of the range {@code [start, end)}. Assumes that the density of records in
   * the range is approximately uniform.
   */
  public synchronized long getPositionForFractionConsumed(double fraction) {
    if (stopOffset == OFFSET_INFINITY) {
      throw new IllegalArgumentException(
          "getPositionForFractionConsumed is not applicable to an unbounded range: " + this);
    }
    return (long) Math.floor(startOffset + fraction * (stopOffset - startOffset));
  }

  @Override
  public synchronized double getFractionConsumed() {
    if (!isStarted()) {
      return 0.0;
    } else if (isDone()) {
      return 1.0;
    } else if (stopOffset == OFFSET_INFINITY) {
      return 0.0;
    } else if (lastRecordStart >= stopOffset) {
      return 1.0;
    } else {
      // E.g., when reading [3, 6) and lastRecordStart is 4, that means we consumed 3 of 3,4,5
      // which is (4 - 3) / (6 - 3) = 33%.

View on GitHub (pinned to 12126d8942)