apache/beam · error · ValueError
Position to be claimed cannot be smaller than the start posi
Error message
Position to be claimed cannot be smaller than the start position of the range. Tried to claim position %r for the range [%r, %r)
What it means
OffsetRestrictionTracker.try_claim() rejects positions below the start of the restriction range. Beam raises this ValueError because the tracker can only acknowledge claims inside [start, stop); claiming before start would violate the restriction contract established at construction.
Source
Thrown at sdks/python/apache_beam/io/restriction_trackers.py:127
return RestrictionProgress(fraction=fraction)
def start_position(self):
return self._range.start
def stop_position(self):
return self._range.stop
def try_claim(self, position):
if (self._last_claim_attempt is not None and
position <= self._last_claim_attempt):
raise ValueError(
'Positions claimed should strictly increase. Trying to claim '
'position %d while last claim attempt was %d.' %
(position, self._last_claim_attempt))
self._last_claim_attempt = position
if position < self._range.start:
raise ValueError(
'Position to be claimed cannot be smaller than the start position '
'of the range. Tried to claim position %r for the range [%r, %r)' %
(position, self._range.start, self._range.stop))
if self._range.start <= position < self._range.stop:
self._current_position = position
return True
return False
def try_split(self, fraction_of_remainder):
if not self._checkpointed:
if self._last_claim_attempt is None:
cur = self._range.start - 1
else:
cur = self._last_claim_attempt
split_point = (
cur + int(max(1, (self._range.stop - cur) * fraction_of_remainder)))View on GitHub (pinned to 12126d8942)
Solutions
- Initialize the iteration cursor from restriction.start() (or tracker.try_split results) instead of 0
- Clamp or skip positions below range.start before claiming
- Check for off-by-one errors where a split boundary was applied twice
- If work before start is needed, request a restriction that includes it rather than claiming outside
Example fix
// before position = 0 while tracker.try_claim(position): ... // after position = restriction.start() while tracker.try_claim(position): ...
Defensive patterns
Strategy: validation
Validate before calling
def safe_claim(tracker, position):
start = tracker.current_restriction().start
if position < start:
position = start
return tracker.try_claim(position) Try / catch
try:
tracker.try_claim(position)
except ValueError as e:
logger.error('Claim below restriction start: %s', e) Prevention
- Initialize iteration from restriction.start(), never 0
- Respect split boundaries returned by try_split
- Test SDFs after splitting to ensure cursors honor new starts
When it happens
Trigger: Calling try_claim(position) where position < restriction.start, e.g. iterating a file from byte 0 while the restriction was split to start at byte 1000.
Common situations: Custom splittable DoFns that ignore the restriction's start when iterating (always starting from zero), or reusing a loop variable initialized outside the range after splitting.
Related errors
- Initializing SDFBoundedSourceRestrictionTracker requires a _
- SDFBoundedSourceRestrictionProvider can only utilize Bounded
- OffsetRestrictionTracker is not done since work in range [%s
- Positions claimed should strictly increase. Trying to claim
- UnboundedSource restriction was neither finished nor checkpo
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/975536938e673d6d.
Report an issue: GitHub.