apache/iceberg · error

Failed to release lock for path: {}

Error message

Failed to release lock for path: {}

What it means

ZkLock.unlock sets the shared count to UNLOCKED to release the maintenance lock. If that ZooKeeper operation throws, the factory logs this warning with the lock path and then rethrows a RuntimeException('Failed to release lock'), so the failure is not swallowed and will surface in the operator/job.

Source

Thrown at flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/ZkLockFactory.java:242

    public boolean isHeld() {
      return isHeld(sharedCount.getVersionedValue());
    }

    private static boolean isHeld(VersionedValue<Integer> versionedValue) {
      try {
        return versionedValue.getValue() == LOCKED;
      } catch (Exception e) {
        throw new RuntimeException("Failed to check Zookeeper lock status", e);
      }
    }

    @Override
    public void unlock() {
      try {
        sharedCount.setCount(UNLOCKED);
        LOG.debug("Released lock for path: {}", lockPath);
      } catch (Exception e) {
        LOG.warn("Failed to release lock for path: {}", lockPath, e);
        throw new RuntimeException("Failed to release lock", e);
      }
    }
  }

  @VisibleForTesting
  RetryPolicy createRetryPolicy() {
    ZKRetryPolicies effectivePolicy =
        (retryPolicy == null) ? ZKRetryPolicies.EXPONENTIAL_BACKOFF : retryPolicy;

    switch (effectivePolicy) {
      case ONE_TIME:
        return new RetryOneTime(baseSleepTimeMs);

      case N_TIME:
        return new RetryNTimes(maxRetries, baseSleepTimeMs);

      case BOUNDED_EXPONENTIAL_BACKOFF:

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Inspect the wrapped cause in the RuntimeException stack trace to confirm the ZooKeeper failure mode (session expired, connection loss).
  2. Increase ZooKeeper session timeout so releases of long-held locks don't run on expired sessions.
  3. Ensure the ZK ensemble is healthy; the lock will remain held until the session expires, so allow the session to lapse or repair connectivity before retrying.
  4. Retry the maintenance job after ZK connectivity is restored.
Defensive patterns

Strategy: retry

Try / catch

try {
  lock.unlock();
} catch (RuntimeException e) {
  LOG.warn("Unlock failed (lock will lapse with ZK session); will retry", e);
  scheduleUnlockRetry();
}

Prevention

When it happens

Trigger: Calling ZkLock.unlock() when the ZooKeeper session is expired or connection is lost, so sharedCount.setCount(UNLOCKED) fails and the catch block logs and wraps the exception.

Common situations: Long-running rewrite commits outliving the ZK session timeout; network interruption between Flink task and ZooKeeper during lock release.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/5e5c6ef1c906ee6b. Report an issue: GitHub.