apache/iceberg · warning · CommitFailedException
Failed to update view %s from catalog %s
Error message
Failed to update view %s from catalog %s
What it means
updateView performs a conditional UPDATE of the view row (WHERE metadata_location = oldMetadataLocation) and expects exactly 1 updated row. If 0 (or more than 1) rows are updated, a CommitFailedException is thrown, meaning the expected prior state was not found or the update did not match exactly one view.
Source
Thrown at core/src/main/java/org/apache/iceberg/jdbc/JdbcViewOperations.java:168
String baseMetadataLocation = base != null ? base.metadataFileLocation() : null;
if (!Objects.equals(baseMetadataLocation, catalogMetadataLocation)) {
throw new CommitFailedException(
"Cannot commit %s: metadata location %s has changed from %s",
viewIdentifier, baseMetadataLocation, catalogMetadataLocation);
}
}
private void updateView(String newMetadataLocation, String oldMetadataLocation)
throws SQLException, InterruptedException {
int updatedRecords =
JdbcUtil.updateView(
connections, catalogName, viewIdentifier, newMetadataLocation, oldMetadataLocation);
if (updatedRecords == 1) {
LOG.debug("Successfully committed to existing view: {}", viewIdentifier);
} else {
throw new CommitFailedException(
"Failed to update view %s from catalog %s", viewIdentifier, catalogName);
}
}
private void createView(String newMetadataLocation) throws SQLException, InterruptedException {
Namespace namespace = viewIdentifier.namespace();
if (PropertyUtil.propertyAsBoolean(catalogProperties, JdbcUtil.STRICT_MODE_PROPERTY, false)
&& !JdbcUtil.namespaceExists(catalogName, connections, namespace)) {
throw new NoSuchNamespaceException(
"Cannot create view %s in catalog %s. Namespace %s does not exist",
viewIdentifier, catalogName, namespace);
}
if (JdbcUtil.tableExists(JdbcUtil.SchemaVersion.V1, catalogName, connections, viewIdentifier)) {
throw new AlreadyExistsException("Table with same name already exists: %s", viewIdentifier);
}
if (JdbcUtil.viewExists(catalogName, connections, viewIdentifier)) {View on GitHub (pinned to 86d9c8fc54)
Solutions
- Refresh the view (viewOps.refresh()) to pick up the new metadata location and retry the commit
- Catch CommitFailedException and retry with backoff — this error is designed to be retried after re-reading state
- Check for duplicate rows in iceberg_views for the same catalog/namespace/view name and clean them up
- Verify the view was not dropped/recreated concurrently by another process
- Serialize writers per view or use an external lock if concurrent commits are routine
Example fix
// before: unconditional retry on same stale object
ops.commit(metadata, base); // fails repeatedly
// after: refresh between attempts
try {
ops.commit(metadata, base);
} catch (CommitFailedException e) {
ops.refresh();
ops.commit(rebase(metadata), ops.current());
} Defensive patterns
Strategy: retry
Validate before calling
// verify exactly one row exists for this view before updating SELECT COUNT(*) FROM iceberg_views WHERE catalog_name = ? AND view_namespace = ? AND view_name = ?; // expect 1
Try / catch
try {
viewOps.commit(request);
} catch (CommitFailedException e) {
viewOps.refresh();
if (viewOps.current() != null) retryAsUpdate(); else retryAsCreate();
} Prevention
- Refresh and re-apply changes after any CommitFailedException
- Detect and clean duplicate rows in iceberg_views
- Serialize concurrent writers per view
- Confirm the view row uses the same catalog_name as your JdbcCatalog config
When it happens
Trigger: Concurrent commit changed the metadata location between validateMetadataLocation and the UPDATE; the view row was deleted concurrently; the view row exists under a different catalog_name, so the conditional UPDATE matches nothing.
Common situations: Race between two writers committing the same view nearly simultaneously; view dropped by another process mid-commit; duplicated catalog rows from a manually seeded or corrupted catalog table.
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
- Cannot commit %s: metadata location %s has changed from %s
- Failed to create view %s in catalog %s
- Failed to update table %s from catalog %s
- Cannot commit %s: metadata location %s has changed from %s
- Cannot commit: Base metadata location '%s' is not same as th
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/442bd8a33da71970.
Report an issue: GitHub.