apache/beam · error · UnsupportedOperationException
Unknown scan type: {}
Error message
Unknown scan type: {} What it means
ScanSource.split() switches over the scan configuration's scan type and throws UnsupportedOperationException for any value it does not explicitly handle (neither TABLE nor BATCH). This is a defensive default branch indicating the ScanConfig carried an unknown or newly-added Iceberg scan type the connector doesn't recognize.
Source
Thrown at sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/ScanSource.java:101
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
public Coder<Row> getOutputCoder() {
return RowCoder.of(View on GitHub (pinned to 12126d8942)
Solutions
- Log/inspect scanConfig.getScanType() to see the unexpected value.
- Fix the code that builds the ScanConfig so it sets a supported scan type (TABLE).
- Align the Beam IO iceberg connector version with the Iceberg library version in use.
- If a new scan type is legitimately needed, add a case for it in ScanSource.split().
Example fix
// before ScanConfig cfg = ScanConfig.builder().build(); // scanType left unset // after ScanConfig cfg = ScanConfig.builder().setScanType(ScanType.TABLE).build();
Defensive patterns
Strategy: validation
Validate before calling
Object t = scanConfig.getScanType();
if (t != ScanType.TABLE && t != ScanType.INCREMENTAL /* supported types */) {
throw new IllegalArgumentException("Unsupported scan type: " + t);
} Try / catch
try {
return source.split(desiredBundles, options);
} catch (UnsupportedOperationException e) {
throw new IllegalStateException("Unknown scan type — check ScanConfig construction and library version alignment", e);
} Prevention
- Always set scanType from the ScanType enum, never a raw/casted value.
- Keep the Beam IO iceberg connector and the Iceberg library versions aligned so enum values match.
- Assert scanType non-null at ScanConfig construction.
When it happens
Trigger: scanConfig.getScanType() returns a value not covered by the switch cases in ScanSource.split(), e.g. a null, custom, or newer Iceberg ScanType enum value.
Common situations: Upgrading the Iceberg library introduced a new scan type the Beam connector version predates; a ScanConfig was built programmatically with a null/default scan type; a custom ScanType implementation was injected.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Unknown DirectoryTreatment: " + directoryTreatment
- Unexpected kind: ${kind}
- Unknown ValueKind: <valueKind>
- Unknown ValueKind: <proto>
- Cannot create enum from value!
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/a494fae5c234102d.
Report an issue: GitHub.