apache/hadoop · error · LeaseException
There is already an existing lease operation
Error message
There is already an existing lease operation
What it means
AbfsLease.acquireLease throws LeaseException("There is already an existing lease operation") when a previous async acquisition Future is still in flight (future != null && !future.isDone()). The class enforces one outstanding acquire per lease object because the callback writes shared state (leaseID, timer task), so overlapping acquires are rejected up front.
Source
Thrown at hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/services/AbfsLease.java:180
}
/**
* Acquire a lease on the given path.
*
* @param retryPolicy Retry policy
* @param numRetries Number of retries
* @param retryInterval Retry interval in seconds
* @param delay Delay in seconds
* @param eTag ETag of the file
* @param tracingContext Tracing context
* @throws LeaseException if the lease cannot be acquired
*/
private void acquireLease(RetryPolicy retryPolicy, int numRetries,
int retryInterval, long delay, final String eTag, TracingContext tracingContext)
throws LeaseException {
LOG.debug("Attempting to acquire lease on {}, retry {}", path, numRetries);
if (future != null && !future.isDone()) {
throw new LeaseException(ERR_LEASE_FUTURE_EXISTS);
}
FutureCallback<AbfsRestOperation> acquireCallback = new FutureCallback<AbfsRestOperation>() {
@Override
public void onSuccess(@Nullable AbfsRestOperation op) {
leaseID = op.getResult().getResponseHeader(HttpHeaderConfigurations.X_MS_LEASE_ID);
if (leaseRefreshDuration != INFINITE_LEASE_DURATION) {
leaseTimerTask = new LeaseTimerTask(client, path,
leaseID, tracingContext);
timer.scheduleAtFixedRate(leaseTimerTask, leaseRefreshDuration / 2,
leaseRefreshDuration / 2);
}
LOG.debug("Acquired lease {} on {}", leaseID, path);
}
@Override
public void onFailure(Throwable throwable) {
try {
if (RetryPolicy.RetryAction.RetryDecision.RETRYView on GitHub (pinned to 2add963021)
Solutions
- Wait for the in-flight acquisition to finish before retrying (poll the lease state / synchronize on the lease object)
- Free the existing lease first, then acquire again, so future is done and state is clean
- Serialize all lease operations per path through a single owner/thread
- Catch LeaseException and back off instead of retrying immediately
Example fix
// before
try {
lease.acquire(...); // may overlap a still-running acquire
} catch (LeaseException e) {
lease.acquire(...); // LeaseException: existing lease operation
}
// after
synchronized (lease) {
while (!lease.isFree()) { // wait for prior future to complete
lease.wait(100);
}
lease.acquire(...);
} Defensive patterns
Strategy: retry
Validate before calling
// Serialize lease acquisition per path; never overlap acquires
synchronized (leaseLock) {
while (acquireInFlight) {
try { leaseLock.wait(100); } catch (InterruptedException ie) {
Thread.currentThread().interrupt(); return;
}
}
acquireInFlight = true;
}
try { lease.acquire(...); } finally {
synchronized (leaseLock) { acquireInFlight = false; leaseLock.notifyAll(); }
} Try / catch
try {
lease.acquire(...);
} catch (LeaseException e) {
if (e.getMessage().contains("already an existing lease operation")) {
Thread.sleep(backoffMs); // let the in-flight future finish
lease.acquire(...); // then retry once
} else throw e;
} Prevention
- One owner thread per lease — no concurrent acquire calls on the same handle
- Free the lease before re-acquiring on recovery paths
- Back off on acquisition failures instead of immediate tight retries
When it happens
Trigger: Triggering acquireLease twice on the same AbfsLease before the first async acquire completes — e.g., a retry loop that immediately re-invokes on timeout, or two threads racing to (re)acquire the lease on the same path/lease handle.
Common situations: Hand-rolled retry logic around lease acquisition; concurrent writers each trying to acquire the lease object; recovery code that re-acquires after failure without waiting for the prior attempt's future to finish.
Related errors
- Attempted to write to file without lease
- Lease desired but no lease threads configured, set fs.azure.
- <src> for client <clientMachine> already exists
- Failed to {} {} for {} on {} because {} is already the curre
- Failed to {} {} for {} on {} because this file lease is curr
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/890b77d176c213d6.
Report an issue: GitHub.