apache/iceberg · warning
Failed to create lock {}
Error message
Failed to create lock {} What it means
MetastoreLock.createLock requests a lock from the Hive Metastore via client.lock(request). On TException (thrift transport/protocol error), it logs this warning with the LockRequest, then attempts to locate the lock via findLock(); if the lock cannot be found the exception is rethrown (on Hive >= 2).
Source
Thrown at hive-metastore/src/main/java/org/apache/iceberg/hive/MetastoreLock.java:309
AtomicBoolean interrupted = new AtomicBoolean(false);
Tasks.foreach(lockRequest)
.retry(Integer.MAX_VALUE - 100)
.exponentialBackoff(
lockCreationMinWaitTime, lockCreationMaxWaitTime, lockCreationTimeout, 2.0)
.shouldRetryTest(
e ->
!interrupted.get()
&& e instanceof LockException
&& HiveVersion.min(HiveVersion.HIVE_2))
.throwFailureWhenFinished()
.run(
request -> {
try {
LockResponse lockResponse = metaClients.run(client -> client.lock(request));
lockInfo.lockId = lockResponse.getLockid();
lockInfo.lockState = lockResponse.getState();
} catch (TException te) {
LOG.warn("Failed to create lock {}", request, te);
try {
// If we can not check for lock, or we do not find it, then rethrow the exception
// Otherwise we are happy as the findLock sets the lockId and the state correctly
if (HiveVersion.min(HiveVersion.HIVE_2)) {
LockInfo lockFound = findLock();
if (lockFound != null) {
lockInfo.lockId = lockFound.lockId;
lockInfo.lockState = lockFound.lockState;
LOG.info("Found lock {} by agentInfo {}", lockInfo, agentInfo);
return;
}
}
throw new LockException(
"Failed to find lock for table %s.%s", databaseName, tableName);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
interrupted.set(true);View on GitHub (pinned to 86d9c8fc54)
Solutions
- Check HMS connectivity and health (metastore logs, network, port)
- Retry the operation — the code already retries via findLock; transient TExceptions often resolve
- Verify Hive version compatibility of the metastore client vs server (HiveVersion.min(HIVE_2) path)
- Increase metastore client timeouts / connection pool settings if under load
Example fix
// before
ops.commit(); // transient TException creating lock
// after
Tasks.foreach(() -> ops.commit())
.retry(3)
.exponentialBackoff(100, 1000)
.throwFailureWhenFinished(); Defensive patterns
Strategy: retry
Validate before calling
// Check HMS reachability before commit-heavy workflows
try (HiveMetaStoreClient c = new HiveMetaStoreClient(hiveConf)) { c.getAllDatabases(); } Try / catch
try { ops.commit(); } catch (org.apache.iceberg.exceptions.CommitFailedException e) { /* re-acquire lock / retry commit */ } Prevention
- Retry commits with exponential backoff (Tasks.foreach retry)
- Keep HMS client timeouts generous for lock-heavy workloads
- Align Hive client and server major versions
- Monitor metastore availability
When it happens
Trigger: Acquiring a Hive lock for a commit when the metastore call fails — HMS unreachable, thrift session expired/invalid, metastore rejecting the lock request.
Common situations: HMS restarted between checkLock and lock acquisition; network blips to metastore; Hive 1.x where findLock behavior differs; concurrent lock contention triggering metastore errors.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Failed to list all tables under namespace ${namespace}
- Metastore operation failed for %s.%s
- Could not find lock with HMSClient {}
- Failed to unlock {}.{}
- Failed to connect to Hive Metastore
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/5fff0a8df16e3a37.
Report an issue: GitHub.