apache/iceberg · error · AlreadyExistsException
View already exists: %s.%s
Error message
View already exists: %s.%s
What it means
doCommit maps Hive metastore's org.apache.hadoop.hive.metastore.api.AlreadyExistsException to Iceberg's AlreadyExistsException with "View already exists: database.viewName". This is raised when the metastore rejects the create/alter because an object with that name already exists, e.g., a concurrent create won the race.
Source
Thrown at hive-metastore/src/main/java/org/apache/iceberg/hive/HiveViewOperations.java:203
currentMetadataLocation(),
sqlFor(metadata));
lock.ensureActive();
try {
persistTable(tbl, updateHiveView, hiveLockEnabled(conf) ? null : baseMetadataLocation);
lock.ensureActive();
commitStatus = CommitStatus.SUCCESS;
} catch (LockException le) {
commitStatus = CommitStatus.UNKNOWN;
throw new CommitStateUnknownException(
"Failed to heartbeat for hive lock while "
+ "committing changes. This can lead to a concurrent commit attempt be able to overwrite this commit. "
+ "Please check the commit history. If you are running into this issue, try reducing "
+ "iceberg.hive.lock-heartbeat-interval-ms.",
le);
} catch (org.apache.hadoop.hive.metastore.api.AlreadyExistsException e) {
throw new AlreadyExistsException(e, "View already exists: %s.%s", database, viewName);
} catch (InvalidObjectException e) {
throw new ValidationException(e, "Invalid Hive object for %s.%s", database, viewName);
} catch (CommitFailedException | CommitStateUnknownException e) {
throw e;
} catch (Throwable e) {
if (e.getMessage() != null
&& e.getMessage()
.contains(
"The table has been modified. The parameter value for key '"
+ BaseMetastoreTableOperations.METADATA_LOCATION_PROP
+ "' is")) {
throw new CommitFailedException(
e, "The view %s.%s has been modified concurrently", database, viewName);
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Catch AlreadyExistsException and fall back to loading or replacing the existing view.
- Check existence first with catalog.viewExists, but keep the catch for the inherent race.
- Pick a different view name or drop the conflicting object intentionally before creating.
- Deduplicate DDL submissions in your orchestration to avoid double creates.
Example fix
// before
views.createView(identifier, ...); // AlreadyExistsException on race
// after
try {
views.createView(identifier, ...);
} catch (AlreadyExistsException e) {
views.loadView(identifier); // adopt existing
} Defensive patterns
Strategy: try-catch
Validate before calling
if (catalog.viewExists(identifier)) {
throw new IllegalStateException("View " + identifier + " already exists; use replace instead of create");
} Try / catch
try {
views.createView(identifier, ...);
} catch (AlreadyExistsException e) {
views.loadView(identifier); // adopt or replaceView instead
} Prevention
- Prefer create-or-replace semantics for idempotent pipelines.
- Guard concurrent creates with an external lock or orchestrator.
- Deduplicate DDL submissions and retries.
- Choose unique names per environment to avoid collisions.
When it happens
Trigger: Committing a view creation when HMS raises its native AlreadyExistsException — an object (view or table) named database.viewName already exists in the metastore at alter/create time.
Common situations: Concurrent view creation by two clients; retrying create after an ambiguous first attempt that actually succeeded; name collisions with existing tables; double submission of the same DDL job.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- View with same name already exists: %s.%s
- %s already exists: %s.%s
- View already exists: %s
- View already exists: %s
- Table already exists: %s.%s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/604c070b0a81f806.
Report an issue: GitHub.