apache/iceberg · error · CommitFailedException
Requirement failed: branch or tag %s is missing, expected %s
Error message
Requirement failed: branch or tag %s is missing, expected %s
What it means
Thrown by AssertRefSnapshotId.validate when the requirement asserts that a branch or tag exists at a given snapshot ID, but the ref does not exist at all in the base metadata. This means the ref was deleted concurrently (or never existed) between when the operation was planned and when the commit validated. The commit fails with CommitFailedException and the operation must be re-planned against current state.
Source
Thrown at core/src/main/java/org/apache/iceberg/UpdateRequirement.java:123
return snapshotId;
}
@Override
public void validate(TableMetadata base) {
SnapshotRef ref = base.ref(name);
if (ref != null) {
String type = ref.isBranch() ? "branch" : "tag";
if (snapshotId == null) {
// a null snapshot ID means the ref should not exist already
throw new CommitFailedException(
"Requirement failed: %s %s was created concurrently", type, name);
} else if (snapshotId != ref.snapshotId()) {
throw new CommitFailedException(
"Requirement failed: %s %s has changed: expected id %s != %s",
type, name, snapshotId, ref.snapshotId());
}
} else if (snapshotId != null) {
throw new CommitFailedException(
"Requirement failed: branch or tag %s is missing, expected %s", name, snapshotId);
}
}
}
class AssertLastAssignedFieldId implements UpdateRequirement {
private final int lastAssignedFieldId;
public AssertLastAssignedFieldId(int lastAssignedFieldId) {
this.lastAssignedFieldId = lastAssignedFieldId;
}
public int lastAssignedFieldId() {
return lastAssignedFieldId;
}
@Override
public void validate(TableMetadata base) {View on GitHub (pinned to 86d9c8fc54)
Solutions
- Refresh table metadata and verify the ref exists before rebuilding and retrying the commit.
- Recreate the missing branch/tag if its removal was unintended, then retry the update.
- Re-plan the operation against the current table state rather than the cached snapshot reference.
- Check for concurrent reference cleanup jobs (ExpireSnapshots, RemoveSnapshots, ref TTL automation) colliding with writers.
Example fix
// before
table.manageSnapshots().fastForward("stage").toSnapshot(id).commit(); // 'stage' deleted concurrently
// after
table.refresh();
if (table.ref("stage") == null) {
table.manageSnapshots().createBranch("stage").commit();
}
table.manageSnapshots().fastForward("stage").toSnapshot(id).commit(); Defensive patterns
Strategy: validation
Validate before calling
table.refresh();
Preconditions.checkArgument(table.ref("stage") != null,
"Ref %s does not exist in current metadata", "stage"); Try / catch
try {
commitRefOperation("stage", id);
} catch (CommitFailedException e) {
if (e.getMessage().contains("is missing")) {
table.refresh();
recreateRefIfIntended();
} else { throw e; }
} Prevention
- Verify the ref exists via table.refs() before operations that assert it
- Check for concurrent cleanup jobs (ExpireSnapshots/ref removal) targeting the same refs
- Confirm the ref name and catalog/database match — typos surface as 'missing'
- Refresh metadata before commit instead of relying on cached state
When it happens
Trigger: Committing AssertRefSnapshotId(name, snapshotId) with a non-null snapshotId when base.ref(name) returns null — the branch/tag was removed by ExpireSnapshots/reference removal or was never created before this commit.
Common situations: Another job drops the branch/tag while a writer holds planned operations against it; a misconfigured environment points at a table where the ref name differs or was never created; REST catalog commits where the client cached an older table version that still contained the ref.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Requirement failed: %s %s has changed: expected id %s != %s
- Requirement failed: %s %s was created concurrently
- Requirement failed: last assigned field id changed: expected
- Requirement failed: current schema changed: expected id %s !
- Requirement failed: last assigned partition id changed: expe
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/effb00520b37bcd2.
Report an issue: GitHub.