apache/iceberg · error · CherrypickAncestorCommitException
Cannot cherrypick snapshot %s: already picked to create ance
Error message
Cannot cherrypick snapshot %s: already picked to create ancestor %s
What it means
Cherry-picking a snapshot requires that the snapshot was not already cherry-picked into the current table's history. CherryPickOperation.validate() checks whether the snapshot is a current ancestor, or whether a previously cherry-picked copy of it already exists as an ancestor (via the source-snapshot-id metadata). Throwing prevents duplicating changes already in the ancestor lineage.
Source
Thrown at core/src/main/java/org/apache/iceberg/CherryPickOperation.java:214
isFastForward,
"Cannot cherry-pick snapshot %s: not append, dynamic overwrite, or fast-forward",
cherrypickSnapshot.snapshotId());
return base.snapshot(cherrypickSnapshot.snapshotId());
} else {
// validate(TableMetadata) is called in apply(TableMetadata) after this apply refreshes the
// table state
return super.apply();
}
}
private static void validateNonAncestor(TableMetadata meta, long snapshotId) {
if (isCurrentAncestor(meta, snapshotId)) {
throw new CherrypickAncestorCommitException(snapshotId);
}
Long ancestorId = lookupAncestorBySourceSnapshot(meta, snapshotId);
if (ancestorId != null) {
throw new CherrypickAncestorCommitException(snapshotId, ancestorId);
}
}
private static void validateReplacedPartitions(
TableMetadata meta, Long parentId, PartitionSet replacedPartitions, FileIO io) {
if (replacedPartitions != null && meta.currentSnapshot() != null) {
ValidationException.check(
parentId == null || isCurrentAncestor(meta, parentId),
"Cannot cherry-pick overwrite, based on non-ancestor of the current state: %s",
parentId);
List<Snapshot> snapshots =
Lists.newArrayList(
SnapshotUtil.ancestorsBetween(
meta.currentSnapshot().snapshotId(), parentId, meta::snapshot));
if (!snapshots.isEmpty()) {
Iterable<CloseableIterable<DataFile>> addedFileTasks =
Iterables.concat(
Iterables.transform(View on GitHub (pinned to 86d9c8fc54)
Solutions
- Do not cherry-pick the same snapshot twice; check ancestry before calling cherryPick.
- Inspect the exception's createAncestorId to find the existing commit and confirm the change is already applied.
- If you intentionally want the change again, create a new snapshot (re-write or re-commit) rather than re-picking.
- Fast-forward/rollback the target branch instead of cherry-picking if the intent is to reach the source state.
Example fix
// before
table.cherryPick(snapshotId); // may already be picked
// after
if (!SnapshotUtil.currentAncestorIds(table).contains(snapshotId)) {
table.cherryPick(snapshotId);
} Defensive patterns
Strategy: validation
Validate before calling
List<Long> ancestors = SnapshotUtil.currentAncestorIds(table);
if (ancestors.contains(snapshotId)) {
throw new IllegalStateException("snapshot already picked: " + snapshotId);
} Prevention
- Track which snapshots have been cherry-picked in your pipeline state.
- Make cherry-pick operations idempotent at the application level.
- Check for CherrypickAncestorCommitException and treat it as already-applied.
When it happens
Trigger: Calling table.cherryPick(snapshotId) where snapshotId is already an ancestor of the current snapshot, or where an earlier cherry-pick of the same source snapshot produced an ancestor commit.
Common situations: Re-running a cherry-pick operation after a prior successful run; scripted retry logic that re-invokes cherryPick on the same snapshot id; applying a branch snapshot that was already picked into main.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Cannot cherrypick snapshot %s: already an ancestor
- this.getClass().getName() + " doesn't implement removedDelet
- Deleted manifest %s could not be found in the latest snapsho
- Failed to validate replaced partitions
- Found conflicting files that can contain records matching pa
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/8e3d299ea4e6329e.
Report an issue: GitHub.