prestodb/presto · error · PrestoException
HIVE_METASTORE_ERROR
HIVE_METASTORE_ERROR
Error message
Table already exists: %s.%s
What it means
During commit() of a new Iceberg table, metastore.persistTable() raised AlreadyExistsException, meaning a table with the same database.name already exists in the Hive Metastore. Presto rethrows it as a PrestoException with code HIVE_METASTORE_ERROR.
Source
Thrown at presto-iceberg/src/main/java/com/facebook/presto/iceberg/HiveTableOperations.java:321
PrincipalPrivileges privileges = new PrincipalPrivileges(
ImmutableMultimap.<String, HivePrivilegeInfo>builder()
.put(table.getOwner(), new HivePrivilegeInfo(SELECT, true, owner, owner))
.put(table.getOwner(), new HivePrivilegeInfo(INSERT, true, owner, owner))
.put(table.getOwner(), new HivePrivilegeInfo(UPDATE, true, owner, owner))
.put(table.getOwner(), new HivePrivilegeInfo(DELETE, true, owner, owner))
.build(),
ImmutableMultimap.of());
try {
if (base == null) {
metastore.createTable(metastoreContext, table, privileges, emptyList());
}
else {
PartitionStatistics tableStats = metastore.getTableStatistics(metastoreContext, database, tableName);
metastore.persistTable(metastoreContext, database, tableName, table, privileges, () -> tableStats, useHMSLock ? ImmutableMap.of() : hmsEnvContext(base.metadataFileLocation()));
}
}
catch (AlreadyExistsException e) {
throw new PrestoException(HIVE_METASTORE_ERROR, format("Table already exists: %s.%s", database, tableName), e);
}
catch (CommitFailedException | CommitStateUnknownException e) {
throw e;
}
catch (Throwable e) {
if (e instanceof PrestoException && e.getCause() instanceof InvalidObjectException) {
throw new ValidationException(e, "Invalid Hive object for %s.%s", database, tableName);
}
if (e.getMessage() != null
&& e.getMessage().contains("Table/View 'HIVE_LOCKS' does not exist")) {
throw new PrestoException(ICEBERG_COMMIT_ERROR,
"Failed to acquire locks from metastore because the underlying metastore "
+ "table 'HIVE_LOCKS' does not exist. This can occur when using an embedded metastore which does not "
+ "support transactions. To fix this use an alternative metastore.",
e);
}
CommitStatus commitStatus;
if (e.getMessage() != nullView on GitHub (pinned to 55bb57d202)
Solutions
- Use CREATE TABLE IF NOT EXISTS (or check existence via SHOW TABLES / system metadata first).
- Drop or rename the existing table if it is stale/unwanted.
- Serialize table-creation logic in deployment scripts to avoid concurrent creates.
Example fix
-- before CREATE TABLE iceberg.db.events (...) ; -- after CREATE TABLE IF NOT EXISTS iceberg.db.events (...);
Defensive patterns
Strategy: validation
Validate before calling
boolean exists = metadata.getSession().getMetadata().getTableHandle(session, tableName) != null;
if (exists) throw new IllegalStateException("Table exists: " + tableName); Try / catch
try { createTable(...); }
catch (PrestoException e) { if (e.getErrorCode() == HIVE_METASTORE_ERROR.toErrorCode()) { /* handle existing table */ } } Prevention
- Use CREATE TABLE IF NOT EXISTS in idempotent scripts.
- Check SHOW TABLES / information_schema before create.
- Guard concurrent deployments from creating the same table.
When it happens
Trigger: Calling CREATE TABLE / CREATE TABLE AS against an Iceberg catalog when the target table already exists in HMS (e.g. created concurrently or left over from a previous run).
Common situations: Idempotency-less CI/CD or migration scripts run twice; race between two sessions creating the same table; inconsistent catalogs where the Iceberg metadata files are absent but the HMS entry exists.
Related errors
- ALREADY_EXISTS
- ICEBERG_INVALID_METADATA
- Metadata location [%s] is not same as table metadata locatio
- Invalid Hive object for %s.%s
- ICEBERG_COMMIT_ERROR
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/a0a5462cca2a18f2.
Report an issue: GitHub.