apache/iceberg · error · CommitFailedException
Requirement failed: last assigned partition id changed: expe
Error message
Requirement failed: last assigned partition id changed: expected id %s != %s
What it means
Thrown by AssertLastAssignedPartitionId.validate when the requirement's lastAssignedPartitionId does not match base.lastAssignedPartitionId() (the highest partition field ID assigned in any spec). Partition field IDs are also monotonic and must never be reused; the assertion detects concurrent partition-spec evolution (AddPartitionField/RemovePartitionField) between planning and commit.
Source
Thrown at core/src/main/java/org/apache/iceberg/UpdateRequirement.java:185
}
}
}
class AssertLastAssignedPartitionId implements UpdateRequirement {
private final int lastAssignedPartitionId;
public AssertLastAssignedPartitionId(int lastAssignedPartitionId) {
this.lastAssignedPartitionId = lastAssignedPartitionId;
}
public int lastAssignedPartitionId() {
return lastAssignedPartitionId;
}
@Override
public void validate(TableMetadata base) {
if (base != null && base.lastAssignedPartitionId() != lastAssignedPartitionId) {
throw new CommitFailedException(
"Requirement failed: last assigned partition id changed: expected id %s != %s",
lastAssignedPartitionId, base.lastAssignedPartitionId());
}
}
}
class AssertDefaultSpecID implements UpdateRequirement {
private final int specId;
public AssertDefaultSpecID(int specId) {
this.specId = specId;
}
public int specId() {
return specId;
}
@OverrideView on GitHub (pinned to 86d9c8fc54)
Solutions
- Refresh the table metadata, rebuild requirements with the current lastAssignedPartitionId, and retry.
- Re-apply the partition-spec change against the refreshed spec so new partition field IDs are assigned from the current max.
- Coordinate partition evolution through a single migration job/owner to avoid racing writers.
- Catch CommitFailedException and retry with backoff; this is the intended recovery path for concurrent-commit conflicts.
Example fix
// before
UpdateRequirement req = new UpdateRequirement.AssertLastAssignedPartitionId(7); // now 9
// after
table.refresh();
UpdateRequirement req = new UpdateRequirement.AssertLastAssignedPartitionId(
table.spec().lastAssignedPartitionId()); Defensive patterns
Strategy: retry
Validate before calling
table.refresh();
if (table.spec().lastAssignedPartitionId() != assertedPartitionId) {
throw new IllegalStateException("Partition spec evolved; re-plan");
} Try / catch
try {
commitPartitionEvolution();
} catch (CommitFailedException e) {
if (e.getMessage().contains("last assigned partition id changed")) {
table.refresh();
reapplySpecChange(table);
} else { throw e; }
} Prevention
- Serialize partition-evolution changes through a single job
- Refresh metadata before spec-related commits
- Derive partition field IDs from the current spec, never constants
- Retry with backoff on CommitFailedException
When it happens
Trigger: Committing updates (e.g. ReplacePartitionSpec or UpdatePartitionSpec flows) whose requirements include AssertLastAssignedPartitionId when base.lastAssignedPartitionId() differs — another writer added or removed partition fields concurrently.
Common situations: Two jobs repartition the table at once; a partition-evolution migration racing with routine partition-field additions; REST catalog commits built from a stale table version where another client already extended the spec.
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: default partition spec changed: expected
- 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
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/8f3f4cd281c8bbd8.
Report an issue: GitHub.