prestodb/presto · error · RuntimeException

Failed to acquire lock

Error message

Failed to acquire lock

What it means

After the lock polling loop finishes, if the lock was never transitioned to ACQUIRED, ThriftHiveMetastore unlocks (if a lockId exists) and throws RuntimeException("Failed to acquire lock"). The metastore never granted the lock within the allowed attempts, so the operation is aborted for safety.

Source

Thrown at presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/thrift/ThriftHiveMetastore.java:1827

                                    }
                                    else if (newState.equals(ACQUIRED)) {
                                        acquired.set(true);
                                    }
                                    else {
                                        throw new RuntimeException(String.format("Failed to acquire lock: %s", newState.name()));
                                    }
                                    return null;
                                })));
                }
            }
            finally {
                if (!acquired.get()) {
                    unlock(metastoreContext, lockId);
                }
            }

            if (!acquired.get()) {
                throw new RuntimeException("Failed to acquire lock");
            }

            return lockId;
        }
        catch (TException e) {
            throw new PrestoException(HIVE_METASTORE_ERROR, e);
        }
        catch (Exception e) {
            throw propagate(e);
        }
    }

    @Override
    public void unlock(MetastoreContext metastoreContext, long lockId)
    {
        try {
            retry()
                    .stopOnIllegalExceptions()

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Identify and stop/complete the competing job holding the metastore lock on the table.
  2. Increase lock acquisition timeout/retry settings (e.g. hive.lock.numretries, check interval) for long operations.
  3. Check for and clean up stale locks left by dead sessions in the metastore lock manager.
  4. Serialize conflicting operations on the table (avoid running big partition drops concurrently with writes).
  5. Catch this RuntimeException and retry with backoff in orchestration scripts.

Example fix

// before: concurrent drop while writer holds lock
executor.submit(() -> metastore.dropPartition(context, db, table, parts, false));

// after: wait for conflicting jobs, then retry with backoff
awaitNoActiveWrites(db, table);
retryWithBackoff(() -> metastore.dropPartition(context, db, table, parts, false));
Defensive patterns

Strategy: retry

Validate before calling

// pre-check lock availability before running the operation
if (metastoreLockHeld(db, table)) { throw new IllegalStateException("Table " + db + "." + table + " is locked; retry later"); }

Try / catch

try {
    metastore.dropPartition(context, db, table, parts, deleteData);
} catch (RuntimeException e) {
    if ("Failed to acquire lock".equals(e.getMessage())) {
        // exponential backoff and retry
    } else throw e;
}

Prevention

When it happens

Trigger: lockAcquire loop exhausts its retry/timeout budget while checkLock keeps returning WAITING (or the loop ends without ACQUIRED) during operations like dropPartition that need an exclusive table lock.

Common situations: Heavy concurrent DDL/DML on the same Hive table keeping the lock permanently WAITING, too-short lock timeout configuration, a hung session holding the lock without heartbeating, metastore under load responding slowly so retries time out.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/77dd61ba7e87789c. Report an issue: GitHub.