apache/iceberg · error · IllegalArgumentException
Unknown starting strategy:
Error message
Unknown starting strategy:
What it means
ContinuousSplitPlannerImpl.startSnapshot resolves the first snapshot for a streaming scan based on scanContext.streamingStartingStrategy(). The switch covers NONE/TABLE_SCAN_THEN_INCREMENTS, INCREMENTS_FROM_SNAPSHOT_ID, and INCREMENTS_FROM_SNAPSHOT_TIMESTAMP; an unrepresented strategy value falls into default and throws IllegalArgumentException('Unknown starting strategy: ...'). This means the StreamingStartingStrategy enum value is not recognized by this planner.
Source
Thrown at flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/source/enumerator/ContinuousSplitPlannerImpl.java:244
case INCREMENTAL_FROM_LATEST_SNAPSHOT_EXCLUSIVE:
return Optional.ofNullable(table.currentSnapshot());
case INCREMENTAL_FROM_EARLIEST_SNAPSHOT:
return Optional.ofNullable(SnapshotUtil.oldestAncestor(table));
case INCREMENTAL_FROM_SNAPSHOT_ID:
Snapshot matchedSnapshotById = table.snapshot(scanContext.startSnapshotId());
Preconditions.checkArgument(
matchedSnapshotById != null,
"Start snapshot id not found in history: " + scanContext.startSnapshotId());
return Optional.of(matchedSnapshotById);
case INCREMENTAL_FROM_SNAPSHOT_TIMESTAMP:
Snapshot matchedSnapshotByTimestamp =
SnapshotUtil.oldestAncestorAfter(table, scanContext.startSnapshotTimestamp());
Preconditions.checkArgument(
matchedSnapshotByTimestamp != null,
"Cannot find a snapshot after: " + scanContext.startSnapshotTimestamp());
return Optional.of(matchedSnapshotByTimestamp);
default:
throw new IllegalArgumentException(
"Unknown starting strategy: " + scanContext.streamingStartingStrategy());
}
}
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Use only documented strategies: TABLE_SCAN_THEN_INCREMENTS, INCREMENTS_FROM_SNAPSHOT_ID, or INCREMENTS_FROM_SNAPSHOT_TIMESTAMP.
- Align all nodes/jars to one Iceberg version so the configured strategy exists in this build.
- If loading strategy from config/checkpoint, validate it parses to a known enum constant before building ScanContext.
- Print the offending value from the message and map it to the closest supported strategy for your use case.
Example fix
// before context.startingStrategy(UNKNOWN_NEW_STRATEGY); // after context.startingStrategy(StreamingStartingStrategy.TABLE_SCAN_THEN_INCREMENTS);
Defensive patterns
Strategy: validation
Validate before calling
StreamingStartingStrategy s = scanContext.streamingStartingStrategy(); Set<StreamingStartingStrategy> supported = Set.of(TABLE_SCAN_THEN_INCREMENTS, INCREMENTS_FROM_SNAPSHOT_ID, INCREMENTS_FROM_SNAPSHOT_TIMESTAMP); Preconditions.checkArgument(supported.contains(s), "Unsupported starting strategy: " + s);
Prevention
- Only use documented StreamingStartingStrategy constants.
- Validate strategy values when deserializing from config or checkpoints.
- Keep job jar and stored state on compatible Iceberg versions.
When it happens
Trigger: Setting a StreamingStartingStrategy value unknown to this build — e.g., a strategy added in a newer Iceberg version used with an older planner, a null/corrupted strategy deserialized from ScanContext, or custom enum extension.
Common situations: Version skew between job jar and saved checkpoint/config carrying the strategy; hand-built ScanContext passing an exotic strategy; typos when constructing strategy programmatically.
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 starting strategy:
- Unrecognized ${WRITE_DISTRIBUTION_MODE}: ${writeMode}
- Unrecognized ${WRITE_DISTRIBUTION_MODE}: ${mode}
- Failed to discover new splits
- Cannot apply unknown unique constraint:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/33475746452d3b6b.
Report an issue: GitHub.