apache/hadoop · warning · RenameFailedException

dest is root directory

Error message

dest is root directory

What it means

initiateRename() maps dst to an S3 key; an empty dstKey means the destination is the bucket root. Renaming anything onto s3a://bucket/ is meaningless, so RenameFailedException 'dest is root directory' is thrown; rename() catches it, logs INFO, and returns false (default exit code).

Source

Thrown at hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/S3AFileSystem.java:2438

   * @throws RenameFailedException if some criteria for a state changing
   * rename was not met. This means work didn't happen; it's not something
   * which is reported upstream to the FileSystem APIs, for which the semantics
   * of "false" are pretty vague.
   * @throws FileNotFoundException there's no source file.
   * @throws IOException on IO failure.
   */
  @Retries.RetryTranslated
  private Pair<S3AFileStatus, S3AFileStatus> initiateRename(
      final Path src,
      final Path dst) throws IOException {
    String srcKey = pathToKey(src);
    String dstKey = pathToKey(dst);

    if (srcKey.isEmpty()) {
      throw new RenameFailedException(src, dst, "source is root directory");
    }
    if (dstKey.isEmpty()) {
      throw new RenameFailedException(src, dst, "dest is root directory");
    }

    // get the source file status; this raises a FNFE if there is no source
    // file.
    S3AFileStatus srcStatus = innerGetFileStatus(src, true,
        StatusProbeEnum.ALL);

    if (srcKey.equals(dstKey)) {
      LOG.debug("rename: src and dest refer to the same file or directory: {}",
          dst);
      throw new RenameFailedException(src, dst,
          "source and dest refer to the same file or directory")
          .withExitCode(srcStatus.isFile());
    }

    S3AFileStatus dstStatus = null;
    try {
      dstStatus = innerGetFileStatus(dst, true, StatusProbeEnum.ALL);

View on GitHub (pinned to 2add963021)

Solutions

  1. Build an explicit destination under root: new Path(new Path("/"), src.getName())
  2. Fix destination computation so the last path element is preserved
  3. Check dst.isRoot() before calling rename

Example fix

// before
Path dst = new Path("/");
fs.rename(src, dst);

// after: keep the file name at bucket top level
Path dst = new Path(new Path("/"), src.getName());
fs.rename(src, dst);
Defensive patterns

Strategy: validation

Validate before calling

if (dst.isRoot()) {
  dst = new Path(new Path("/"), src.getName());
}
fs.rename(src, dst);

Prevention

When it happens

Trigger: rename(src, new Path("/")) or any dst qualifying to the bucket root; 'move file to top level' logic that drops the filename when building the destination.

Common situations: Destination built as dst.getParent() of a top-level path; normalization dropping the last path element; code assuming rename-to-directory semantics where the directory is the root itself.

Related errors


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