apache/iceberg · error · RuntimeException
Failed to check Zookeeper lock status
Error message
Failed to check Zookeeper lock status
What it means
ZkLock.isHeld(VersionedValue<Integer>) calls versionedValue.getValue() on the SharedCount data; any exception (e.g. ConnectionLoss, NoNode, deserialization failure) is wrapped in RuntimeException('Failed to check Zookeeper lock status'). The lock state could not be read from the stored counter.
Source
Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/ZkLockFactory.java:232
}
return acquired;
} catch (Exception e) {
LOG.warn("Failed to acquire Zookeeper lock", e);
return false;
}
}
@Override
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 =View on GitHub (pinned to 86d9c8fc54)
Solutions
- Check getCause() for KeeperException.ConnectionLoss vs NoNode vs deserialization errors.
- Restore ZooKeeper connectivity/quorum; the Curator retryPolicy should absorb brief outages.
- Recreate the lock znode if it was deleted externally (start the counter again at 0/UNLOCKED).
- Ensure all writers use the same Iceberg/Curator versions to avoid incompatible counter serialization.
- Increase session timeout and tune the Curator retry policy for unstable networks.
Defensive patterns
Strategy: retry
Validate before calling
// preflight read zkCli.sh -server zk:2181 get /iceberg/lock/<lockId>/task
Try / catch
try {
boolean held = lock.tryLock(/*waitTime*/);
} catch (RuntimeException e) {
LOG.warn("ZK lock status check failed, retrying", e.getCause());
// retry with backoff; treat repeated failure as 'not held'
} Prevention
- Keep session timeouts above max GC pause
- Do not delete lock znodes externally while jobs run
- Use identical Iceberg/Curator versions across all writers
- Tune the Curator retry policy for your network's failure profile
When it happens
Trigger: tryLock()/isHeld() reading the shared count znode when the ZooKeeper session is lost, the znode was deleted externally, the stored data cannot be deserialized (corrupted or written by an incompatible version), or the retry policy is exhausted.
Common situations: ZooKeeper ensemble failover during isHeld; external cleanup script removed the lock znode; another Iceberg/Flink version wrote counter bytes in a different format; long GC pause causing session expiry mid-read.
Related errors
- Failed to initialize SharedCount
- Failed to initialize SharedCount
- Connection to Zookeeper timed out
- Interrupted while connecting to Zookeeper
- Failed to release lock
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/67e775b996556297.
Report an issue: GitHub.