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;
    }

    @Override

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Refresh metadata, read the current currentSchemaId, rebuild the requirements, and retry the commit.
  2. 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.
  3. Sequence schema changes through one pipeline/owner to prevent concurrent current-schema switches.
  4. 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

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


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/ba9029d494db3ab8. Report an issue: GitHub.