apache/hadoop · error · FileAlreadyExistsException

Cannot rename symlink {} to its target {}

Error message

Cannot rename symlink {} to its target {}

What it means

FileAlreadyExistsException thrown when renaming a symlink to the exact path the symlink points to. Such a rename would create a self-referential entry (the link resolving through itself), so validateDestination rejects it before any other destination check.

Source

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

    } finally {
      fsd.writeUnlock();
    }
    if (renameIIP != null) {
      fsd.getEditLog().logRename(
          srcIIP.getPath(), dstIIP.getPath(), mtime, logRetryCache);
    }
    // this rename never overwrites the dest so files deleted and collected
    // are irrelevant.
    return createRenameResult(fsd, renameIIP, false, null);
  }

  private static void validateDestination(
      String src, String dst, INode srcInode)
      throws IOException {
    String error;
    if (srcInode.isSymlink() &&
        dst.equals(srcInode.asSymlink().getSymlinkString())) {
      throw new FileAlreadyExistsException("Cannot rename symlink " + src
          + " to its target " + dst);
    }
    // dst cannot be a directory or a file under src
    if (dst.startsWith(src)
        && dst.charAt(src.length()) == Path.SEPARATOR_CHAR) {
      error = "Rename destination " + dst
          + " is a directory or file under source " + src;
      NameNode.stateChangeLog.warn("DIR* FSDirectory.unprotectedRenameTo: "
          + error);
      throw new IOException(error);
    }

    if (FSDirectory.isExactReservedName(src)
        || FSDirectory.isExactReservedName(dst)) {
      error = "Cannot rename to or from /.reserved";
      throw new InvalidPathException(error);
    }
  }

View on GitHub (pinned to 2add963021)

Solutions

  1. Rename the link to a different path, or delete the link if only the target is wanted.
  2. Guard in code: resolve the link target (getFileLinkStatus/getSymlink) and compare it with the destination before renaming.

Example fix

// before
fs.rename(linkPath, targetPath); // FileAlreadyExistsException: Cannot rename symlink to its target

// after
if (fs.getFileLinkStatus(linkPath).isSymlink()
    && targetPath.makeQualified(fs.getUri(), fs.getWorkingDirectory()).equals(
        fs.getLinkTarget(linkPath).makeQualified(fs.getUri(), linkPath.getParent()))) {
  // refuse: would rename a symlink onto its own target
} else {
  fs.rename(linkPath, targetPath);
}
Defensive patterns

Strategy: validation

Validate before calling

if (fs.getFileLinkStatus(src).isSymlink()) {
  Path target = fs.getLinkTarget(src).makeQualified(fs.getUri(), src.getParent());
  Path qdst = dst.makeQualified(fs.getUri(), fs.getWorkingDirectory());
  if (target.equals(qdst)) {
    throw new FileAlreadyExistsException("Refusing to rename symlink onto its own target");
  }
}
fs.rename(src, dst);

Try / catch

try {
  fs.rename(src, dst);
} catch (FileAlreadyExistsException e) {
  if (e.getMessage() != null && e.getMessage().contains("to its target")) {
    // renaming a link onto its own target: pick another destination or delete the link
  }
  throw e;
}

Prevention

When it happens

Trigger: `hdfs dfs -mv /link /target` where /link's stored target string is exactly /target; automation that 'normalizes' symlinks by moving them onto the files they reference; link-farm reorganization scripts.

Common situations: Symlinked warehouse layouts being flattened; tools that rename links assuming posix mv-into-directory semantics; snapshot copies where links and targets collide.

Related errors


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