apache/hadoop · error · IOException
File is not under construction: {}
Error message
File is not under construction: {} What it means
Replay of OP_CLOSE found the file already complete. For edit logs at or newer than the HDFS-2991 bugfix layout version, a second OP_CLOSE is an error; only pre-0.23.1 logs (HDFS-2991 could log OP_CLOSE twice) are tolerated. The throw means the namespace state and the edit stream disagree about the file.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogLoader.java:507
final INodesInPath iip = fsDir.getINodesInPath(path, DirOp.READ);
final INodeFile file = INodeFile.valueOf(iip.getLastINode(), path);
// Update the salient file attributes.
file.setAccessTime(addCloseOp.atime, Snapshot.CURRENT_STATE_ID, false);
file.setModificationTime(addCloseOp.mtime, Snapshot.CURRENT_STATE_ID);
ErasureCodingPolicy ecPolicy =
FSDirErasureCodingOp.unprotectedGetErasureCodingPolicy(
fsDir.getFSNamesystem(), iip);
updateBlocks(fsDir, addCloseOp, iip, file, ecPolicy);
// Now close the file
if (!file.isUnderConstruction() &&
logVersion <= LayoutVersion.BUGFIX_HDFS_2991_VERSION) {
// There was a bug (HDFS-2991) in hadoop < 0.23.1 where OP_CLOSE
// could show up twice in a row. But after that version, this
// should be fixed, so we should treat it as an error.
throw new IOException(
"File is not under construction: " + path);
}
// One might expect that you could use removeLease(holder, path) here,
// but OP_CLOSE doesn't serialize the holder. So, remove the inode.
if (file.isUnderConstruction()) {
fsNamesys.getLeaseManager().removeLease(file.getId());
file.toCompleteFile(file.getModificationTime(), 0,
fsNamesys.getBlockManager().getMinReplication());
}
break;
}
case OP_APPEND: {
AppendOp appendOp = (AppendOp) op;
final String path = renameReservedPathsOnUpgrade(appendOp.path,
logVersion);
if (FSNamesystem.LOG.isDebugEnabled()) {
FSNamesystem.LOG.debug(op.opCode + ": " + path +
" clientName " + appendOp.clientName +View on GitHub (pinned to 2add963021)
Solutions
- Make fsimage and edit logs in all configured name directories come from the same checkpoint epoch; never mix files from different backups
- Run 'hdfs namenode -recover' to skip the inconsistent transaction
- Remove duplicated or overlapping segment files and let the NameNode load a clean chain
Example fix
# before: image from backup A mixed with edits from backup B -> duplicate OP_CLOSE cp backupA/fsimage_* /hadoop/dfs/name/current/ && cp backupB/edits_* /hadoop/dfs/name/current/ # after: restore the whole current/ directory from one backup rm -rf /hadoop/dfs/name/current && cp -a backupA/current /hadoop/dfs/name/current
Defensive patterns
Strategy: validation
Validate before calling
// image and retained segments must chain with no gap or overlap NNStorage s = new NNStorage(conf, dirs); long imgTx = s.getMostRecentCheckpointTxId(); // each segment's [first,last] txid parsed from its filename must start at // imgTx + 1 and continue contiguously; any duplicate OP_CLOSE candidate // shows up as an overlapping segment
Try / catch
try {
loader.loadFSEdits(storage, 0);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().startsWith("File is not under construction")) {
// duplicate OP_CLOSE vs stale image state: restore a single-epoch backup
// or restart with 'hdfs namenode -recover' to skip it
}
throw e;
} Prevention
- Restore the entire name directory from one backup, never image from one and edits from another
- Checkpoint before upgrades and downgrades
- After manual recovery, verify the segment chain before starting the NameNode
When it happens
Trigger: Two OP_CLOSE records for the same file in logs with a post-bugfix layout version; an fsimage that already contains the closed file while edits re-close it; duplicated or mis-ordered segments in the name directories.
Common situations: fsimage restored from one backup and edits from another point in time; duplicate segment files left by a failed manual recovery; rollback or downgrade leaving overlapping transactions.
Related errors
- The layout version {} supports inodeId but gave bogus inodeI
- Mismatched block IDs or generation stamps for the old last b
- Mismatched block IDs or generation stamps, attempting to rep
- Trying to remove a block from file {} which is not under con
- Trying to remove more than one block from file {}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/e28988c73cc96e57.
Report an issue: GitHub.