{"record":{"id":"ebe763eb0c5ca4ef","repo":"apache/iceberg","slug":"requirement-failed-default-partition-spec-changed","errorCode":null,"errorMessage":"Requirement failed: default partition spec changed: expected id %s != %s","messagePattern":"Requirement failed: default partition spec changed: expected id (.+?) != (.+?)","errorType":"exception","errorClass":"CommitFailedException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/UpdateRequirement.java","lineNumber":206,"sourceCode":"      }\n    }\n  }\n\n  class AssertDefaultSpecID implements UpdateRequirement {\n    private final int specId;\n\n    public AssertDefaultSpecID(int specId) {\n      this.specId = specId;\n    }\n\n    public int specId() {\n      return specId;\n    }\n\n    @Override\n    public void validate(TableMetadata base) {\n      if (specId != base.defaultSpecId()) {\n        throw new CommitFailedException(\n            \"Requirement failed: default partition spec changed: expected id %s != %s\",\n            specId, base.defaultSpecId());\n      }\n    }\n  }\n\n  class AssertDefaultSortOrderID implements UpdateRequirement {\n    private final int sortOrderId;\n\n    public AssertDefaultSortOrderID(int sortOrderId) {\n      this.sortOrderId = sortOrderId;\n    }\n\n    public int sortOrderId() {\n      return sortOrderId;\n    }\n\n    @Override","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/UpdateRequirement.java#L188-L224","documentation":"Thrown by AssertDefaultSpecId.validate when the requirement's specId differs from base.defaultSpecId(). This requirement asserts the table's default partition spec is unchanged since the update was planned. A mismatch means a concurrent writer switched the default spec (partition evolution), so the commit is rejected to prevent writing data under assumptions about the wrong spec.","triggerScenarios":"Committing updates with AssertDefaultSpecId when base.defaultSpecId() != specId — another job ran UpdatePartitionSpec (replacing the default spec) or reset the default spec concurrently.","commonSituations":"A partition-evolution migration running while writers commit other metadata changes; two admin jobs both altering partitioning; commits from a client whose cached metadata predates a spec change; REST catalog conflicts between independent services managing the table.","solutions":["Refresh metadata, read base.defaultSpecId(), rebuild the requirements, and retry the commit.","Re-evaluate the operation under the new default spec — writes planned for the old spec may need re-partitioning before retry.","Gate partition-evolution changes behind a single coordinated job so concurrent default-spec switches cannot occur.","Catch CommitFailedException and retry the update against fresh metadata with backoff."],"exampleFix":"// before\nUpdateRequirement req = new UpdateRequirement.AssertDefaultSpecId(0); // default now spec 1\n// after\ntable.refresh();\nUpdateRequirement req = new UpdateRequirement.AssertDefaultSpecId(\n    table.spec().specId());","handlingStrategy":"retry","validationCode":"table.refresh();\nif (table.spec().specId() != expectedDefaultSpecId) {\n  throw new IllegalStateException(\"Default spec changed; re-plan writes\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  commitWithRequirements(reqs);\n} catch (CommitFailedException e) {\n  if (e.getMessage().contains(\"default partition spec changed\")) {\n    table.refresh();\n    reqs = rebuildRequirements(table);\n  } else { throw e; }\n}","preventionTips":["Check defaultSpecId before writes that assume a particular spec","Coordinate partition-evolution migrations with active writers","Refresh the table before each commit batch","Implement standard CommitFailedException retry/backoff"],"tags":["concurrency","partition-spec","commit-failed","iceberg"],"backgroundTag":"invalid-state-transition","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}