apache/beam · error · UnsupportedOperationException

BATCH scan not supported

Error message

BATCH scan not supported

What it means

Beam's Iceberg ScanSource.split() only supports Iceberg TABLE (and presumably INCREMENTAL) scan types; a BATCH scan configuration is rejected with UnsupportedOperationException. BATCH scans (the Iceberg BatchScan API) are not implemented in this connector. This is a hard capability limit, not a transient error.

Solutions

  1. Use a TABLE (or incremental) scan configuration instead of BATCH when building the Beam source.
  2. Do your BATCH scan outside Beam (directly via Iceberg's Table.scan().planFiles()) if you don't need Beam splitting.
  3. If you own the code, implement the BATCH case or convert the batch scan into a TABLE scan task list before creating the source.

Example fix

// before
ScanConfig cfg = ScanConfig.builder().setScanType(ScanType.BATCH).build();
// after
ScanConfig cfg = ScanConfig.builder().setScanType(ScanType.TABLE).build();
Defensive patterns

Strategy: validation

Validate before calling

if (scanConfig.getScanType() == ScanType.BATCH) {
  throw new IllegalArgumentException("BATCH scans are unsupported by Beam's Iceberg ScanSource; use TABLE scans");
}

Try / catch

try {
  return source.split(desiredBundles, pipelineOptions);
} catch (UnsupportedOperationException e) {
  // fall back to a TABLE-scan based source
  throw new IllegalStateException("Reconfigure scan to TABLE type; BATCH unsupported", e);
}

Prevention

When it happens

Trigger: A ScanConfig with scanType == BATCH is passed to ScanSource.split() when Beam tries to split the source into bundles, typically when constructing a BoundedSource from a table-scanned batch scan.

Common situations: Using Iceberg's batch scan API results directly with the Beam connector; wiring a custom scan config with ScanType.BATCH; running an unbounded/streaming read path that maps to BATCH scans.

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/018c0eb21f433690. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/ScanSource.java:99

    switch (scanConfig.getScanType()) {
      case TABLE:
        TableScan tableScan = getTableScan();
        if (desiredBundleSizeBytes > 0) {
          tableScan =
              tableScan.option(TableProperties.SPLIT_SIZE, Long.toString(desiredBundleSizeBytes));
        }

        try (CloseableIterable<CombinedScanTask> tasks = tableScan.planTasks()) {
          for (CombinedScanTask combinedScanTask : tasks) {
            splits.add(new ScanTaskSource(scanConfig, combinedScanTask));
          }
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
        break;
      case BATCH:
        throw new UnsupportedOperationException("BATCH scan not supported");
      default:
        throw new UnsupportedOperationException("Unknown scan type: " + scanConfig.getScanType());
    }

    return splits;
  }

  @Override
  public long getEstimatedSizeBytes(PipelineOptions options) throws Exception {
    return wholeTableReadTask().sizeBytes();
  }

  @Override
  public void populateDisplayData(DisplayData.Builder builder) {
    super.populateDisplayData(builder);
  }

  @Override

View on GitHub (pinned to 12126d8942)