apache/iceberg · error · CommitFailedException
Requirement failed: current schema changed: expected id %s !
Error message
Requirement failed: current schema changed: expected id %s != %s
What it means
Thrown by AssertCurrentSchemaId.validate when the requirement's schemaId differs from base.currentSchemaId(). This requirement asserts that the table's current schema is still the one the update was planned against. A mismatch means a concurrent writer switched the current schema (SetCurrentSchema or a schema change that re-points it), so the update is rejected to avoid applying changes based on a stale schema.
Source
Thrown at core/src/main/java/org/apache/iceberg/UpdateRequirement.java:164
}
}
}
class AssertCurrentSchemaID implements UpdateRequirement {
private final int schemaId;
public AssertCurrentSchemaID(int schemaId) {
this.schemaId = schemaId;
}
public int schemaId() {
return schemaId;
}
@Override
public void validate(TableMetadata base) {
if (schemaId != base.currentSchemaId()) {
throw new CommitFailedException(
"Requirement failed: current schema changed: expected id %s != %s",
schemaId, base.currentSchemaId());
}
}
}
class AssertLastAssignedPartitionId implements UpdateRequirement {
private final int lastAssignedPartitionId;
public AssertLastAssignedPartitionId(int lastAssignedPartitionId) {
this.lastAssignedPartitionId = lastAssignedPartitionId;
}
public int lastAssignedPartitionId() {
return lastAssignedPartitionId;
}
@OverrideView on GitHub (pinned to 86d9c8fc54)
Solutions
- Refresh metadata, read the current currentSchemaId, rebuild the requirements, and retry the commit.
- If the update must target a specific schema, verify whether the new current schema still satisfies the operation; otherwise re-plan against the new schema.
- Sequence schema changes through one pipeline/owner to prevent concurrent current-schema switches.
- Catch CommitFailedException and retry the whole update transaction against fresh metadata.
Example fix
// before
UpdateRequirement req = new UpdateRequirement.AssertCurrentSchemaId(3); // table now at 4
// after
table.refresh();
UpdateRequirement req =
new UpdateRequirement.AssertCurrentSchemaId(table.schema().schemaId()); Defensive patterns
Strategy: retry
Validate before calling
table.refresh();
if (table.schema().schemaId() != expectedSchemaId) {
throw new IllegalStateException("Current schema changed; re-plan");
} Try / catch
try {
commitWithRequirements(reqs);
} catch (CommitFailedException e) {
if (e.getMessage().contains("current schema changed")) {
table.refresh();
reqs = rebuildRequirements(table);
} else { throw e; }
} Prevention
- Refresh metadata before building AssertCurrentSchemaId requirements
- Avoid concurrent jobs that switch the current schema
- Verify operation validity against the new schema after any conflict
- Retry commits against refreshed base metadata rather than recycling stale requirements
When it happens
Trigger: Committing updates with AssertCurrentSchemaId when base.currentSchemaId() != schemaId — another writer changed the current schema via UpdateSchema or an explicit set-current-schema operation before this commit validated.
Common situations: Concurrent ALTER TABLE ... SET TBLPROPERTIES ('current-schema') style operations or engine-side schema swaps; a writer that planned against schema v3 while a migration rolled the table to schema v4; REST catalog conflict between two services both evolving schema.
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
- Requirement failed: %s %s was created concurrently
- Requirement failed: %s %s has changed: expected id %s != %s
- Requirement failed: branch or tag %s is missing, expected %s
- Requirement failed: last assigned field id changed: expected
- Requirement failed: last assigned partition id changed: expe
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/ba9029d494db3ab8.
Report an issue: GitHub.