apache/hadoop · error · LeaseExpiredException
File is not open for writing: {} (inode {}) {}
Error message
File is not open for writing: {} (inode {}) {} What it means
checkLease's regular-file case: the file exists but is no longer under construction — it was closed (by close, lease recovery, or another writer) while this client still believed it held the lease. The next addBlock/close on that src fails with LeaseExpiredException('File is not open for writing').
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java:3262
: "Holder " + holder + " does not have any open files.");
}
INodeFile checkLease(INodesInPath iip, String holder, long fileId)
throws LeaseExpiredException, FileNotFoundException {
String src = iip.getPath();
INode inode = iip.getLastINode();
assert hasReadLock(RwLockMode.FS);
if (inode == null) {
throw new FileNotFoundException("File does not exist: "
+ leaseExceptionString(src, fileId, holder));
}
if (!inode.isFile()) {
throw new LeaseExpiredException("INode is not a regular file: "
+ leaseExceptionString(src, fileId, holder));
}
final INodeFile file = inode.asFile();
if (!file.isUnderConstruction()) {
throw new LeaseExpiredException("File is not open for writing: "
+ leaseExceptionString(src, fileId, holder));
}
// No further modification is allowed on a deleted file.
// A file is considered deleted, if it is not in the inodeMap or is marked
// as deleted in the snapshot feature.
if (isFileDeleted(file)) {
throw new FileNotFoundException("File is deleted: "
+ leaseExceptionString(src, fileId, holder));
}
final String owner = file.getFileUnderConstructionFeature().getClientName();
if (holder != null && !owner.equals(holder)) {
throw new LeaseExpiredException("Client (=" + holder
+ ") is not the lease owner (=" + owner + ": "
+ leaseExceptionString(src, fileId, holder));
}
return file;
}
View on GitHub (pinned to 2add963021)
Solutions
- Reopen with append() (or re-create) and continue from the last flushed length — the old handle is dead
- Fix the root cause: close streams in finally, keep the lease renewer thread healthy, avoid JVM pauses near the lease limits
- If another writer legitimately took over, switch to single-writer coordination instead of fighting the lease
Example fix
// before: stale handle from before the lease was reclaimed
out.write(buf, 0, n); out.close(); // LeaseExpiredException
// after
long len = fs.getFileStatus(path).getLen();
try (FSDataOutputStream out = ((DistributedFileSystem) fs).append(path)) {
/* re-append everything beyond len */
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!((DistributedFileSystem) fs).isFileClosed(path)) {
// still open (by us or someone else); if not by us, expect lease contention
} Try / catch
catch (LeaseExpiredException e) { if (e.getMessage() != null && e.getMessage().contains("not open for writing")) { long len = fs.getFileStatus(src).getLen(); reopenAppendAndContinueFrom(len); } else throw e; } Prevention
- Close FSDataOutputStream in finally; never cache write handles across long pauses
- Monitor DFSClient 'Failed to renew lease' warnings and fail fast
- Keep writer JVM GC pauses well under the soft limit (default 60s)
When it happens
Trigger: A client's write handle outlives its lease: another client/admin ran recoverLease, hard-limit expiry closed the file, or the file was closed and the same handle kept being used; the next block allocation then fails.
Common situations: Long GC pauses or a stalled DFSClient lease-renewer thread so the NN reclaims and closes the lease; automation ran recoverLease on live files; retry logic writing to an already-closed file.
Related errors
- ${message}: ${currentFilePath} [${t}]
- Cannot append to a replica with unexpected generation stamp
- The new generation stamp {newGS} should be greater than the
- Cannot append to an unfinalized replica {b}
- Corrupted replica {replicaInfo} with a length of {numBytes}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/acb194e1a2c6a7b0.
Report an issue: GitHub.