apache/iceberg · error · RuntimeException
Failed to check Zookeeper lock status
Error message
Failed to check Zookeeper lock status
What it means
The lock's isHeld(VersionedValue) reads the current counter value from Zookeeper to compare against LOCKED; any exception doing so (session expired, connection loss, deserialization) is wrapped in this RuntimeException. Callers cannot determine lock ownership, so the failure is propagated rather than assumed.
Source
Thrown at flink/v2.1/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 the wrapped KeeperException (ConnectionLoss vs SessionExpired)
- Rely on Curator's retry policy — increase retries/timeout in createRetryPolicy configuration
- Reacquire the lock: after SessionExpired, recreate the lock factory/connection
- Stabilize the network between Flink TaskManagers and the Zookeeper quorum
Defensive patterns
Strategy: try-catch
Validate before calling
// preflight: verify session is live before lock operations
if (!curator.getZookeeperClient().isConnected()) { reconnect(); } Try / catch
try {
boolean held = lock.isHeld();
} catch (RuntimeException e) {
if (e.getMessage().contains("Failed to check Zookeeper lock status")) {
// treat as unknown ownership: reacquire the lock after reconnect
} else { throw e; }
} Prevention
- Keep GC pauses and network partitions below Zookeeper session timeout
- Configure Curator retry policy with sufficient retries
- Monitor session-expiration events and rebuild the lock factory on them
When it happens
Trigger: tryLock or isHeld invoked while the Zookeeper session is expired or the connection is down; versionedValue.getValue() throws on corrupt/unreadable counter data.
Common situations: Long GC pauses or network partitions expiring the Zookeeper session; Zookeeper ensemble restart while a maintenance task holds/queries the lock; reconnect window during a SharedCount read.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- Failed to check Zookeeper lock status
- Connection to Zookeeper timed out
- Interrupted while connecting to Zookeeper
- Failed to initialize SharedCount
- Failed to check Zookeeper lock status
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/3be343c01fe90bdc.
Report an issue: GitHub.