{"record":{"id":"6f3674a787f6cef7","repo":"apache/hadoop","slug":"failed-to-rename-since-it-is-prohibited-to-rename","errorCode":null,"errorMessage":"Failed to rename since it is prohibited to rename dest path %s under src path %s","messagePattern":"Failed to rename since it is prohibited to rename dest path (.+?) under src path (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-cloud-storage-project/hadoop-tos/src/main/java/org/apache/hadoop/fs/tosfs/RawFileSystem.java","lineNumber":306,"sourceCode":"    return true;\n  }\n\n  private Path checkAndGetDstPath(Path src, Path dest) throws IOException {\n    FileStatus destStatus = getFileStatusOrNull(dest);\n    // 1. Rebuilding the destination path\n    Path finalDstPath = dest;\n    if (destStatus != null && destStatus.isDirectory()) {\n      finalDstPath = new Path(dest, src.getName());\n    }\n\n    // 2. No need to check the dest path because renaming itself is allowed.\n    if (src.equals(finalDstPath)) {\n      return finalDstPath;\n    }\n\n    // 3. Ensure the source path cannot be the ancestor of destination path.\n    if (RawFSUtils.inSubtree(src, finalDstPath)) {\n      throw new IOException(String.format(\"Failed to rename since it is prohibited to \" +\n          \"rename dest path %s under src path %s\", finalDstPath, src));\n    }\n\n    // 4. Ensure the destination path doesn't exist.\n    FileStatus finalDstStatus = destStatus;\n    if (destStatus != null && destStatus.isDirectory()) {\n      finalDstStatus = getFileStatusOrNull(finalDstPath);\n    }\n    if (finalDstStatus != null) {\n      throw new FileAlreadyExistsException(\n          String.format(\"Failed to rename since the dest path %s already exists.\", finalDstPath));\n    } else {\n      return finalDstPath;\n    }\n  }\n\n  private FileStatus checkAndGetSrcStatus(Path src) throws IOException {\n    // throw FileNotFoundException if src not found.","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-tos/src/main/java/org/apache/hadoop/fs/tosfs/RawFileSystem.java#L288-L324","documentation":"Thrown by the rename-destination validation in RawFileSystem when the final destination path is inside the source subtree (RawFSUtils.inSubtree(src, finalDstPath) is true). Renaming a directory into its own descendant would create a cycle, so the operation is rejected before any storage call.","triggerScenarios":"rename('/a/b', '/a/b/c') or any rename where dest (after the 'dest is an existing dir' adjustment of appending src.getName()) is a strict descendant of src, e.g. renaming a directory into a subdirectory of itself.","commonSituations":"Shell-script style 'move into self' mistakes ported to the object store; job code computing destination paths from source paths and accidentally nesting them; archive routines that build dest as src + '/archive'.","solutions":["Choose a destination outside the source subtree, e.g. rename('/a/b', '/a/c') instead of rename('/a/b', '/a/b/c')","If the intent is to move under a sibling directory, target the sibling: rename('/a/b', '/a-dst/b')","Validate before calling: reject when dest.isDescendant(src) (or use RawFSUtils.inSubtree semantics) with your own error message"],"exampleFix":"// before\nfs.rename(new Path(\"/a/b\"), new Path(\"/a/b/c\")); // dest under src -> IOException\n\n// after\nfs.rename(new Path(\"/a/b\"), new Path(\"/a/c\")); // dest outside src subtree","handlingStrategy":"validation","validationCode":"static boolean isUnder(Path src, Path dst) {\n  // true when dst is a descendant of src\n  for (Path p = dst.getParent(); p != null; p = p.getParent()) {\n    if (p.equals(src)) return true;\n  }\n  return false;\n}\nif (isUnder(makeQualified(src), makeQualified(dst))) throw new IllegalArgumentException(\"dest under src\");","typeGuard":null,"tryCatchPattern":"try { fs.rename(src, dst); }\ncatch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"prohibited to rename\")) { /* fix paths */ }\n  else throw e;\n}","preventionTips":["Compute destination paths from a different root than the source","Unit-test rename helpers with the 'into own subtree' case","Remember dest-dir adjustment: dest may become dest/srcName before validation"],"tags":["rename","path-validation","cycle-prevention","tos"],"backgroundTag":"rename-into-own-subtree","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}