apache/beam · error · RuntimeError

SDFBoundedSourceRestrictionProvider can only utilize Bounded

Error message

SDFBoundedSourceRestrictionProvider can only utilize BoundedSource

What it means

SDFBoundedSourceRestrictionProvider adapts legacy BoundedSources to the splittable-DoFn model and can therefore only operate on BoundedSource elements. _check_source raises RuntimeError when the element source is not a BoundedSource instance. This fails fast in initial_restriction and related restriction-provider methods.

Source

Thrown at sdks/python/apache_beam/io/iobase.py:1864

        restriction._source_bundle.start_position,
        restriction._source_bundle.stop_position))


class _SDFBoundedSourceRestrictionProvider(core.RestrictionProvider):
  """
  A `RestrictionProvider` that is used by SDF for `BoundedSource`.

  This restriction provider initializes restriction based on input
  element that is expected to be of BoundedSource type.
  """
  def __init__(self, desired_chunk_size=None, restriction_coder=None):
    self._desired_chunk_size = desired_chunk_size
    self._restriction_coder = (
        restriction_coder or _SDFBoundedSourceWrapperRestrictionCoder())

  def _check_source(self, src):
    if not isinstance(src, BoundedSource):
      raise RuntimeError(
          'SDFBoundedSourceRestrictionProvider can only utilize BoundedSource')

  def initial_restriction(self, element_source: BoundedSource):
    self._check_source(element_source)
    range_tracker = element_source.get_range_tracker(None, None)
    return _SDFBoundedSourceRestriction(
        SourceBundle(
            None,
            element_source,
            range_tracker.start_position(),
            range_tracker.stop_position()))

  def create_tracker(self, restriction):
    return _SDFBoundedSourceRestrictionTracker(restriction)

  def split(self, element, restriction):
    if self._desired_chunk_size is None:
      try:

View on GitHub (pinned to 12126d8942)

Solutions

  1. Make the element passed to the DoFn an instance of apache_beam.io.iobase.BoundedSource.
  2. Implement BoundedSource methods (estimate_size, split, read, get_range_tracker) on your custom source class.
  3. Use the built-in FileBasedSource/RangeSource helpers, which are already BoundedSources.
  4. If wrapping an existing Source, convert it into a BoundedSource implementation.

Example fix

# before
| beam.ParDo(MySdfDoFn(), 'not-a-source')
# after
| beam.ParDo(MySdfDoFn(), MyBoundedSource(file_pattern))
Defensive patterns

Strategy: type-guard

Validate before calling

from apache_beam.io.iobase import BoundedSource
assert isinstance(element_source, BoundedSource), type(element_source)

Type guard

def is_bounded_source(src) -> bool:
    from apache_beam.io.iobase import BoundedSource
    return isinstance(src, BoundedSource)

Try / catch

try:
    restriction = provider.initial_restriction(element_source)
except RuntimeError as e:
    if 'BoundedSource' in str(e): log.error('%s is not a BoundedSource', type(element_source))

Prevention

When it happens

Trigger: Using a DoFn that declares the restriction provider (via _check_source path) but receives a plain callable, a custom Source (non-BoundedSource), or any other object in place of a BoundedSource.

Common situations: Migrating old custom sources to SDF and wiring a non-BoundedSource class; passing a file pattern or config object instead of the constructed BoundedSource; Beam-internal callers processing element payloads of the wrong type after deserialization.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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