{"record":{"id":"2ceb0c17d35d09d9","repo":"apache/hadoop","slug":"router-federation-rename-can-t-rename-snapshot-pat-2ceb0c","errorCode":null,"errorMessage":"Router federation rename can't rename snapshot path. dst={}({})","messagePattern":"Router federation rename can't rename snapshot path\\. dst=(.+?)\\((.+?)\\)","errorType":"exception","errorClass":"AccessControlException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/RouterFederationRename.java","lineNumber":198,"sourceCode":"        new Path(\"hdfs://\" + srcLoc.getNameserviceId() + srcLoc.getDest());\n    srcPath.getFileSystem(conf).access(srcPath.getParent(), FsAction.WRITE);\n    // check dst path permission.\n    Path dstPath =\n        new Path(\"hdfs://\" + dstLoc.getNameserviceId() + dstLoc.getDest());\n    dstPath.getFileSystem(conf).access(dstPath.getParent(), FsAction.WRITE);\n  }\n\n  static void checkSnapshotPath(RemoteLocation src, RemoteLocation dst)\n      throws AccessControlException {\n    if (src.getDest()\n        .contains(HdfsConstants.SEPARATOR_DOT_SNAPSHOT_DIR + Path.SEPARATOR)) {\n      throw new AccessControlException(\n          \"Router federation rename can't rename snapshot path. src=\" + src\n              .getSrc() + \"(\" + src + \")\");\n    }\n    if (dst.getDest()\n        .contains(HdfsConstants.SEPARATOR_DOT_SNAPSHOT_DIR + Path.SEPARATOR)) {\n      throw new AccessControlException(\n          \"Router federation rename can't rename snapshot path. dst=\" + dst\n              .getSrc() + \"(\" + dst + \")\");\n    }\n  }\n\n  /**\n   * Build router federation rename job moving data from src to dst.\n   * @param srcNs the source namespace id.\n   * @param dstNs the dst namespace id.\n   * @param src the source path.\n   * @param dst the dst path.\n   */\n  private BalanceJob buildRouterRenameJob(String srcNs, String dstNs,\n      String src, String dst) throws IOException {\n    checkConfiguration(conf);\n    Path srcPath = new Path(\"hdfs://\" + srcNs + src);\n    Path dstPath = new Path(\"hdfs://\" + dstNs + dst);\n    boolean forceCloseOpen =","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/RouterFederationRename.java#L180-L216","documentation":"Companion to the src check: RouterFederationRename.checkSnapshotPath also rejects a rename whose destination path addresses something inside a snapshot, i.e. the dst RemoteLocation destination contains '/.snapshot/'. Writing into a snapshot path is invalid in HDFS itself, and the fed rename pre-check surfaces it as an AccessControlException before any job is submitted.","triggerScenarios":"rename(src, dst) across namespaces where the resolved dst contains /.snapshot/ - for example renaming onto /mount/.snapshot/snap1/newname or any target beneath a .snapshot directory.","commonSituations":"Scripts that construct destination paths from snapshot listings; mistaken cut-and-paste of a snapshot path as the rename target; tooling unaware that .snapshot is reserved.","solutions":["Target a live writable directory as the destination, never a path containing /.snapshot/","Validate dst before issuing the rename: reject any path with a /.snapshot/ component client-side","If the intent was restoring snapshot content, copy out of the snapshot with distcp to a regular destination instead"],"exampleFix":"# before\nhdfs dfs -fs hdfs://router -mv /src /dstmount/.snapshot/snap1/restored\n# after\nhdfs dfs -fs hdfs://router -mv /src /dstmount/restored","handlingStrategy":"validation","validationCode":"// Validate the destination before rename\nif (dst.contains(HdfsConstants.SEPARATOR_DOT_SNAPSHOT_DIR + Path.SEPARATOR)) {\n  throw new IllegalArgumentException(\"Cannot rename into snapshot path: \" + dst);\n}","typeGuard":"boolean isSnapshotPath(String path) {\n  return path != null && path.contains(\"/.snapshot/\");\n}","tryCatchPattern":"try {\n  dfs.rename(src, dst);\n} catch (AccessControlException ace) {\n  if (ace.getMessage() != null && ace.getMessage().contains(\"can't rename snapshot path. dst=\")) {\n    // choose a live writable directory as destination\n  }\n  throw ace;\n}","preventionTips":["Build destination paths from trusted live-directory inputs, never from snapshot listings","Block /.snapshot/ in any path-building helper your tooling uses for write APIs","Treat .snapshot as reserved: reject it in client-side path validators"],"tags":["hdfs","router","federation","rename","snapshot","validation"],"backgroundTag":"snapshot-path-not-supported","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}