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

  1. Make fsimage and edit logs in all configured name directories come from the same checkpoint epoch; never mix files from different backups
  2. Run 'hdfs namenode -recover' to skip the inconsistent transaction
  3. 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

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


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/e28988c73cc96e57. Report an issue: GitHub.