{"record":{"id":"572acc4bbef6396e","repo":"apache/iceberg","slug":"metastore-operation-failed-for-s-s-572acc","errorCode":null,"errorMessage":"Metastore operation failed for %s.%s","messagePattern":"Metastore operation failed for (.+?)\\.(.+?)","errorType":"exception","errorClass":"LockException","httpStatus":null,"severity":"error","filePath":"hive-metastore/src/main/java/org/apache/iceberg/hive/MetastoreLock.java","lineNumber":249,"sourceCode":"    } catch (WaitingForLockException e) {\n      timeout = true;\n      duration = System.currentTimeMillis() - start;\n    } catch (TException e) {\n      thriftError = e;\n    } finally {\n      if (!lockInfo.lockState.equals(LockState.ACQUIRED)) {\n        unlock(Optional.of(lockInfo.lockId));\n      }\n    }\n\n    if (!lockInfo.lockState.equals(LockState.ACQUIRED)) {\n      if (timeout) {\n        throw new LockException(\n            \"Timed out after %s ms waiting for lock on %s.%s\", duration, databaseName, tableName);\n      }\n\n      if (thriftError != null) {\n        throw new LockException(\n            thriftError, \"Metastore operation failed for %s.%s\", databaseName, tableName);\n      }\n\n      // Just for safety. We should not get here.\n      throw new LockException(\n          \"Could not acquire the lock on %s.%s, lock request ended in state %s\",\n          databaseName, tableName, lockInfo.lockState);\n    } else {\n      return lockInfo.lockId;\n    }\n  }\n\n  /**\n   * Creates a lock, retrying if possible on failure.\n   *\n   * @return The {@link LockInfo} object for the successfully created lock\n   * @throws LockException When we are not able to fill the hostname for lock creation, or there is\n   *     an error during lock creation","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/hive-metastore/src/main/java/org/apache/iceberg/hive/MetastoreLock.java#L231-L267","documentation":"The lock acquisition loop ended in a non-ACQUIRED state but neither the timeout nor a recorded thrift error explains it, so this safety-net LockException is thrown. It indicates an unmet invariant in the locking protocol (lockId null, unexpected state, or lost bookkeeping).","triggerScenarios":"acquireLock exits the loop with lockState != ACQUIRED, timeout=false and thriftError=null — e.g. checkLock returned an unexpected state transition path or the lockId acquisition path skipped state updates.","commonSituations":"Metastore returning unexpected lock states (ABORTED/error paths not classified); races between lock creation and checkLock; Hive metastore version quirks in lock semantics.","solutions":["Retry the commit — this is treated as a lock acquisition failure and the commit should be re-attempted.","Inspect the metastore lock table (SHOW LOCKS / HIVE_LOCKS rows) for the stuck or aborted lock.","Upgrade the iceberg-hive-metastore/Hive versions if the metastore exhibits known lock-state bugs.","Report persistent occurrences with the lock state details; this path indicates an invariant violation."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  commit();\n} catch (CommitFailedException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Could not acquire the lock\")) {\n    // unexpected lock state: re-acquire lock and retry; escalate if persistent\n  }\n}","preventionTips":["Keep Hive metastore and Iceberg versions current to avoid lock-state bugs.","Inspect SHOW LOCKS output when this recurs; collect state details for bug reports.","Treat this as an invariant failure: add monitoring/alerting rather than silent retry loops."],"tags":["hive","locking","invariant","metastore"],"backgroundTag":"internal-invariant-violation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}