apache/hadoop · error · FileAlreadyExistsException

The source {} and destination {} are the same

Error message

The source {} and destination {} are the same

What it means

FileAlreadyExistsException from renameToInt when source and destination resolve to the exact same path. Rename-to-self is rejected up front during destination validation, before overwrite checks - even Options.Rename.OVERWRITE cannot make it meaningful (it would delete the source).

Source

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

   */
  static RenameResult unprotectedRenameTo(FSDirectory fsd,
      final INodesInPath srcIIP, final INodesInPath dstIIP, long timestamp,
      BlocksMapUpdateInfo collectedBlocks, Options.Rename... options)
      throws IOException {
    assert fsd.hasWriteLock();
    boolean overwrite = options != null
        && Arrays.asList(options).contains(Options.Rename.OVERWRITE);

    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);

View on GitHub (pinned to 2add963021)

Solutions

  1. Fix the caller to pass a genuinely different destination path.
  2. Guard in code: compare qualified src and dst and treat equality as a no-op.
  3. Inspect the job's configuration for miswired source/destination parameters.

Example fix

// before
fs.rename(src, dst); // src and dst qualified to the same path

// after
if (!src.makeQualified(fs.getUri(), fs.getWorkingDirectory())
        .equals(dst.makeQualified(fs.getUri(), fs.getWorkingDirectory()))) {
  fs.rename(src, dst);
}
Defensive patterns

Strategy: validation

Validate before calling

Path qs = src.makeQualified(fs.getUri(), fs.getWorkingDirectory());
Path qd = dst.makeQualified(fs.getUri(), fs.getWorkingDirectory());
if (qs.equals(qd)) {
  return; // src == dst: nothing to do
}
fs.rename(src, dst);

Try / catch

try {
  fs.rename(src, dst);
} catch (FileAlreadyExistsException e) {
  if (src.makeQualified(fs.getUri(), fs.getWorkingDirectory())
      .equals(dst.makeQualified(fs.getUri(), fs.getWorkingDirectory()))) {
    return; // no-op, ignore
  }
  throw e;
}

Prevention

When it happens

Trigger: `hdfs dfs -mv /a /a`; programmatic fs.rename(src, dst) where both Paths are equal after qualification (same URI, no trailing-slash difference); templated pipelines substituting identical src/dst values from config.

Common situations: Config-driven promotion pipelines where the source and destination variables collapse to the same value (same table rename, env-to-env copy with matching envs); path normalization differences hiding the equality from the caller but not the NameNode.

Related errors


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