{"record":{"id":"b766280d62c1bf49","repo":"apache/hadoop","slug":"rename-of-to-is-not-allowed-no-eligible-des","errorCode":null,"errorMessage":"Rename of {} to {} is not allowed, no eligible destination in the same namespace was found","messagePattern":"Rename of (.+?) to (.+?) is not allowed, no eligible destination in the same namespace was found","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/RouterFederationRename.java","lineNumber":100,"sourceCode":"    this.rpcServer = rpcServer;\n    this.conf = conf;\n  }\n\n  /**\n   * Router federation rename across namespaces.\n   *\n   * @param src the source path. There is no mount point under the src path.\n   * @param dst the dst path.\n   * @param srcLocations the remote locations of src.\n   * @param dstLocations the remote locations of dst.\n   * @throws IOException if rename fails.\n   * @return true if rename succeeds.\n   */\n  public boolean routerFedRename(final String src, final String dst,\n      final List<RemoteLocation> srcLocations,\n      final List<RemoteLocation> dstLocations) throws IOException {\n    if (!rpcServer.isEnableRenameAcrossNamespace()) {\n      throw new IOException(\"Rename of \" + src + \" to \" + dst\n          + \" is not allowed, no eligible destination in the same namespace was\"\n          + \" found\");\n    }\n    if (srcLocations.size() != 1 || dstLocations.size() != 1) {\n      throw new IOException(\"Rename of \" + src + \" to \" + dst + \" is not\"\n          + \" allowed. The remote location should be exactly one.\");\n    }\n    RemoteLocation srcLoc = srcLocations.get(0);\n    RemoteLocation dstLoc = dstLocations.get(0);\n    checkSnapshotPath(srcLoc, dstLoc);\n    checkPermission(srcLoc, dstLoc);\n\n    UserGroupInformation routerUser = UserGroupInformation.getLoginUser();\n\n    try {\n      // as router user with saveJournal and task submission privileges\n      return routerUser.doAs((PrivilegedExceptionAction<Boolean>) () -> {\n        // Build and submit router federation rename job.","sourceCodeStart":82,"sourceCodeEnd":118,"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#L82-L118","documentation":"Router federation rename (RouterFederationRename.routerFedRename) rejects a rename whose source and destination fall in different namespaces when cross-namespace rename is disabled. isEnableRenameAcrossNamespace() is true only when dfs.federation.router.federation.rename.option is not NONE (the default is NONE), so by default the router refuses any rename that cannot be answered by a single nameservice. The message means: no eligible destination in the same namespace was found and fed-rename support is off.","triggerScenarios":"ClientProtocol#rename(src, dst) through the router where the mount table resolves src and dst to different nameservices (or to different RemoteLocation namespaces), while dfs.federation.router.federation.rename.option=NONE (default). The router's location-for-path lookup finds no single namespace containing both, falls into routerFedRename, and the option check throws.","commonSituations":"Default router configuration after enabling HDFS federation; mount table split so a data directory and its target directory live in different subclusters; teams expecting plain rename to work across mounts without enabling the distcp-based fed rename.","solutions":["Restructure the mount table so src and dst resolve into the same namespace (single mount entry covering both), then retry the rename","Enable router federation rename: set dfs.federation.router.federation.rename.option=DISTCP plus the required dfs.federation.router.federation.rename.map / .bandwidth settings, and restart the router","If fed rename is not acceptable, copy data with distcp (or a two-step copy+delete) instead of rename"],"exampleFix":"# before\nhdfs dfs -fs hdfs://router:8888 -mv /ns0mount/data /ns1mount/data   # fails: different namespaces\n# after (hdfs-site.xml on router, then restart)\n<property><name>dfs.federation.router.federation.rename.option</name><value>DISTCP</value></property>\n<property><name>dfs.federation.router.federation.rename.map</name><value>10</value></property>\n<property><name>dfs.federation.router.federation.rename.bandwidth</name><value>100</value></property>","handlingStrategy":"validation","validationCode":"// Pre-check both sides resolve to the same namespace before attempting rename\nList<RemoteLocation> s = resolver.getLocationsForPath(src, false);\nList<RemoteLocation> d = resolver.getLocationsForPath(dst, false);\nif (!s.get(0).getNameserviceId().equals(d.get(0).getNameserviceId())\n    && !fedRenameEnabled(conf)) {\n  throw new UnsupportedOperationException(\n      \"Cross-namespace rename requires dfs.federation.router.federation.rename.option=DISTCP\");\n}","typeGuard":"boolean fedRenameEnabled(Configuration conf) {\n  return !\"NONE\".equals(conf.get(\"dfs.federation.router.federation.rename.option\", \"NONE\")\n      .toUpperCase(Locale.ROOT));\n}","tryCatchPattern":"try {\n  fs.rename(srcPath, dstPath);\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"no eligible destination in the same namespace\")) {\n    // either restructure mounts so both paths share a namespace, or route via distcp\n  }\n  throw e;\n}","preventionTips":["Design mount layout so directories commonly renamed together share one mount entry","Decide up front whether cross-namespace rename is supported and set the rename.option accordingly","Wrap client rename logic with a same-namespace pre-check when fed rename is disabled"],"tags":["hdfs","router","federation","rename","mount-table","cross-namespace","configuration"],"backgroundTag":"cross-namespace-rename-denied","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}