apache/hadoop · error · IOException

rename destination cannot be the root

Error message

rename destination cannot be the root

What it means

IOException thrown when the rename destination resolves to the filesystem root (dstIIP.length() == 1). The root always exists and is immutable as a rename target, so 'rename to /' is rejected during destination validation before quota or overwrite checks.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirRenameOp.java:407

    final String src = srcIIP.getPath();
    final String dst = dstIIP.getPath();
    final String error;
    final INode srcInode = srcIIP.getLastINode();
    List<INodeDirectory> srcSnapshottableDirs = new ArrayList<>();
    validateRenameSource(fsd, srcIIP, srcSnapshottableDirs);

    // validate the destination
    if (dst.equals(src)) {
      throw new FileAlreadyExistsException("The source " + src +
          " and destination " + dst + " are the same");
    }
    validateDestination(src, dst, srcInode);

    if (dstIIP.length() == 1) {
      error = "rename destination cannot be the root";
      NameNode.stateChangeLog.warn("DIR* FSDirectory.unprotectedRenameTo: " +
          error);
      throw new IOException(error);
    }

    BlockStoragePolicySuite bsps = fsd.getBlockStoragePolicySuite();
    fsd.ezManager.checkMoveValidity(srcIIP, dstIIP);
    final INode dstInode = dstIIP.getLastINode();
    List<INodeDirectory> dstSnapshottableDirs = new ArrayList<>();
    if (dstInode != null) { // Destination exists
      validateOverwrite(src, dst, overwrite, srcInode, dstInode);
      FSDirSnapshotOp.checkSnapshot(fsd, dstIIP, dstSnapshottableDirs);
    }

    INode dstParent = dstIIP.getINode(-2);
    if (dstParent == null) {
      error = "rename destination parent " + dst + " not found.";
      NameNode.stateChangeLog.warn("DIR* FSDirectory.unprotectedRenameTo: " +
          error);
      throw new FileNotFoundException(error);
    }

View on GitHub (pinned to 2add963021)

Solutions

  1. Give the destination a real name: `hdfs dfs -mv /data /data2` (HDFS rename has no 'move into directory' form - dst is the final path).
  2. Validate in code that dst is not root (dst.isRoot()) before calling rename.

Example fix

# before
hdfs dfs -mv /data /      # IOException: rename destination cannot be the root

# after
hdfs dfs -mv /data /data2
Defensive patterns

Strategy: validation

Validate before calling

if (dst.isRoot()) {
  throw new IllegalArgumentException("Rename destination cannot be the root; give the destination a name");
}
fs.rename(src, dst);

Try / catch

try {
  fs.rename(src, dst);
} catch (IOException e) {
  if (dst.isRoot() && e.getMessage().contains("cannot be the root")) {
    // rebuild dst as parent-of-src + new name
    dst = new Path(src.getParent(), newDstName);
    fs.rename(src, dst);
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: `hdfs dfs -mv /data /` where the destination normalizes to the root; programmatic fs.rename(src, new Path("/")); destination strings built by concatenation that end up empty and default to '/'.

Common situations: Scripts intending 'move up one level' - in HDFS the destination must be the full new path (/data2), not /; template bugs stripping the file name and leaving the root; copying commands between posix mv semantics and HDFS semantics.

Related errors


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