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
- Use a TABLE (or incremental) scan configuration instead of BATCH when building the Beam source.
- Do your BATCH scan outside Beam (directly via Iceberg's Table.scan().planFiles()) if you don't need Beam splitting.
- 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
- Always set scanType explicitly (TABLE) when constructing ScanConfig for Beam reads.
- Do not feed raw Iceberg batch scan results into Beam sources.
- Add an assertion in pipeline construction code that rejects BATCH scans early.
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
- Cannot read format
- Encountered an error when creating a RecordWriter for table
- Encountered an error when parsing filter
- smallBatchTag and largeBatchTag must be different
- Threshold must be a positive integer
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);
}
@OverrideView on GitHub (pinned to 12126d8942)