{"record":{"id":"45d7e0d74595973e","repo":"apache/hadoop","slug":"cannot-rename-to-or-from-reserved","errorCode":null,"errorMessage":"Cannot rename to or from /.reserved","messagePattern":"Cannot rename to or from /\\.reserved","errorType":"exception","errorClass":"InvalidPathException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirRenameOp.java","lineNumber":564,"sourceCode":"    if (srcInode.isSymlink() &&\n        dst.equals(srcInode.asSymlink().getSymlinkString())) {\n      throw new FileAlreadyExistsException(\"Cannot rename symlink \" + src\n          + \" to its target \" + dst);\n    }\n    // dst cannot be a directory or a file under src\n    if (dst.startsWith(src)\n        && dst.charAt(src.length()) == Path.SEPARATOR_CHAR) {\n      error = \"Rename destination \" + dst\n          + \" is a directory or file under source \" + src;\n      NameNode.stateChangeLog.warn(\"DIR* FSDirectory.unprotectedRenameTo: \"\n          + error);\n      throw new IOException(error);\n    }\n\n    if (FSDirectory.isExactReservedName(src)\n        || FSDirectory.isExactReservedName(dst)) {\n      error = \"Cannot rename to or from /.reserved\";\n      throw new InvalidPathException(error);\n    }\n  }\n\n  private static void validateOverwrite(\n      String src, String dst, boolean overwrite, INode srcInode, INode dstInode)\n      throws IOException {\n    String error;// It's OK to rename a file to a symlink and vice versa\n    if (dstInode.isDirectory() != srcInode.isDirectory()) {\n      error = \"Source \" + src + \" and destination \" + dst\n          + \" must both be directories\";\n      NameNode.stateChangeLog.warn(\"DIR* FSDirectory.unprotectedRenameTo: \"\n          + error);\n      throw new IOException(error);\n    }\n    if (!overwrite) { // If destination exists, overwrite flag must be true\n      error = \"rename destination \" + dst + \" already exists\";\n      NameNode.stateChangeLog.warn(\"DIR* FSDirectory.unprotectedRenameTo: \"\n          + error);","sourceCodeStart":546,"sourceCodeEnd":582,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirRenameOp.java#L546-L582","documentation":"InvalidPathException when either endpoint of the rename is exactly '/.reserved' (FSDirectory.isExactReservedName). /.reserved is a virtual namespace exposing internal state (e.g., /.reserved/raw for raw encrypted bytes) and cannot be created, deleted, or renamed as a whole; its children like /.reserved/raw/<path> are addressed individually.","triggerScenarios":"`hdfs dfs -mv /.reserved /backup`; programmatic rename with either Path equal to /.reserved; backup/migration tools that iterate top-level entries of / and attempt to move the reserved node.","commonSituations":"Backup or tree-copy scripts walking '/' naively; experiments embedding /.reserved into path templates; security audits that try to relocate the raw view.","solutions":["Exclude /.reserved from any move/rename logic (skip reserved names).","To operate on raw zone contents, address /.reserved/raw/<real-path> explicitly instead of renaming the reserved root.","Whitelist known-good top-level directories rather than blacklisting."],"exampleFix":"# before\nhdfs dfs -mv /.reserved /backup/.reserved   # InvalidPathException\n\n# after\n# /.reserved is virtual: skip it entirely in move scripts\nhdfs dfs -mv /data /backup/data","handlingStrategy":"validation","validationCode":"static boolean isReservedRoot(Path p) {\n  return \"/.reserved\".equals(p.toUri().getPath());\n}\nif (isReservedRoot(src) || isReservedRoot(dst)) {\n  throw new org.apache.hadoop.fs.InvalidPathException(\"Cannot rename to or from /.reserved\");\n}\nfs.rename(src, dst);","typeGuard":null,"tryCatchPattern":"try {\n  fs.rename(src, dst);\n} catch (InvalidPathException e) {\n  // /.reserved is a virtual namespace; skip it in move/backup logic\n  throw e;\n}","preventionTips":["Skip /.reserved in any tool that walks '/' (backup, copy, migrate).","Address raw encrypted data via /.reserved/raw/<path>, never by moving the reserved root."],"tags":["hdfs","rename","reserved-path","invalid-path"],"backgroundTag":"reserved-path","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}