apache/iceberg · warning · CommitFailedException
Failed to create view %s in catalog %s
Error message
Failed to create view %s in catalog %s
What it means
After the INSERT in doCommitCreateView, createView expects exactly 1 inserted row. If the insert reports a different row count, a CommitFailedException is thrown, meaning the atomic create-insert did not produce the expected single view row despite pre-checks passing.
Source
Thrown at core/src/main/java/org/apache/iceberg/jdbc/JdbcViewOperations.java:197
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)) {
throw new AlreadyExistsException("View already exists: %s", viewIdentifier);
}
int insertRecord =
JdbcUtil.doCommitCreateView(
connections, catalogName, namespace, viewIdentifier, newMetadataLocation);
if (insertRecord == 1) {
LOG.debug("Successfully committed to new view: {}", viewIdentifier);
} else {
throw new CommitFailedException(
"Failed to create view %s in catalog %s", viewIdentifier, catalogName);
}
}
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Refresh catalog state and check whether the view was actually created before retrying
- Catch CommitFailedException and retry as an update (load existing view) if the view now exists
- Check for a unique-key violation wrapped as the cause — that means a concurrent creator won the race
- Remove DB triggers or unusual driver behavior that distort affected-row counts on the catalog tables
Example fix
// before
ops.commit(newMeta, null); // blind create retry
// after
try {
ops.commit(newMeta, null);
} catch (CommitFailedException e) {
if (catalog.viewExists(id)) { /* update path */ } else { /* retry create */ }
} Defensive patterns
Strategy: retry
Validate before calling
// pre-check before create
if (catalog.viewExists(id)) { /* use update path */ } Try / catch
try {
viewOps.commit(newMetadata, null);
} catch (CommitFailedException e) {
viewOps.refresh();
if (viewOps.current() != null) retryAsUpdate(); else retryCreateWithBackoff();
} Prevention
- Treat create failures as races: re-check catalog state before retrying
- Avoid DB triggers on catalog tables that distort affected-row counts
- Use a stable JDBC driver known to report accurate update counts
When it happens
Trigger: Concurrent insert of the same view between viewExists check and the INSERT (insert affected 0 rows due to constraint), or an anomalous driver result (>1 rows affected, e.g. triggers/misbehaving driver).
Common situations: Race between two createView calls for the same identifier where the loser's INSERT matches no rows or violates the unique key; database triggers altering affected-row counts; driver-specific rowcount semantics.
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
- Failed to update view %s from catalog %s
- Cannot commit %s: metadata location %s has changed from %s
- Cannot create view %s in catalog %s. Namespace %s does not e
- Table with same name already exists: %s
- Cannot commit %s: concurrent update detected
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/b732ec783ddb95ea.
Report an issue: GitHub.