{"record":{"id":"33f51be7630caa51","repo":"apache/hadoop","slug":"can-t-rename-across-file-systems","errorCode":null,"errorMessage":"Can't rename across file systems.","messagePattern":"Can't rename across file systems\\.","errorType":"validation","errorClass":"HadoopIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/ViewDistributedFileSystem.java","lineNumber":550,"sourceCode":"  @SuppressWarnings(\"deprecation\")\n  @Override\n  public void rename(Path src, Path dst, final Options.Rename... options)\n      throws IOException {\n    if (this.vfs == null) {\n      super.rename(src, dst, options);\n      return;\n    }\n\n    ViewFileSystemOverloadScheme.MountPathInfo<FileSystem> mountSrcPathInfo =\n        this.vfs.getMountPathInfo(src, getConf());\n\n    ViewFileSystemOverloadScheme.MountPathInfo<FileSystem> mountDstPathInfo =\n        this.vfs.getMountPathInfo(dst, getConf());\n\n    //Check both in same cluster.\n    if (!mountSrcPathInfo.getTargetFs().getUri()\n        .equals(mountDstPathInfo.getTargetFs().getUri())) {\n      throw new HadoopIllegalArgumentException(\n          \"Can't rename across file systems.\");\n    }\n\n    FileUtil.rename(mountSrcPathInfo.getTargetFs(),\n        mountSrcPathInfo.getPathOnTarget(), mountDstPathInfo.getPathOnTarget(),\n        options);\n  }\n\n  @Override\n  public boolean truncate(final Path f, final long newLength)\n      throws IOException {\n    if (this.vfs == null) {\n      return super.truncate(f, newLength);\n    }\n    return this.vfs.truncate(f, newLength);\n  }\n\n  public boolean delete(final Path f, final boolean recursive)","sourceCodeStart":532,"sourceCodeEnd":568,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/ViewDistributedFileSystem.java#L532-L568","documentation":"ViewDistributedFileSystem.renameWithOptions resolves the mount path info for both src and dst and throws HadoopIllegalArgumentException(\"Can't rename across file systems.\") when the target filesystem URIs differ. Rename can only be delegated atomically to a single cluster, so cross-cluster renames are rejected up front.","triggerScenarios":"Renaming between mounts that resolve to different clusters (hdfs://cluster1/user/a to hdfs://cluster2/user/b), including clusters with the same content but different addressed namespaces.","commonSituations":"Federated viewfs namespaces; scripts moving data between clusters through the view; destination paths that silently resolve onto another mount due to mount-table overlap.","solutions":["Keep rename source and destination under the same mount (same target cluster)","For cross-cluster moves use distcp, or FileUtil.copy followed by delete, and accept the non-atomic window","Pre-check both paths with getMountPathInfo and compare target URIs before renaming"],"exampleFix":"// before\nvfs.rename(src, dst, Rename.OVERWRITE);\n\n// after: explicit cross-cluster move\nViewFileSystemOverloadScheme.MountPathInfo<FileSystem> s =\n    ((ViewDistributedFileSystem) vfs).getMountPathInfo(src, conf);\nViewFileSystemOverloadScheme.MountPathInfo<FileSystem> d =\n    ((ViewDistributedFileSystem) vfs).getMountPathInfo(dst, conf);\nFileUtil.copy(s.getTargetFs(), s.getPathOnTarget(),\n    d.getTargetFs(), d.getPathOnTarget(), true, true, conf);\ns.getTargetFs().delete(s.getPathOnTarget(), true);","handlingStrategy":"validation","validationCode":"ViewDistributedFileSystem vdfs = (ViewDistributedFileSystem) vfs;\nURI srcFs = vdfs.getMountPathInfo(src, conf).getTargetFs().getUri();\nURI dstFs = vdfs.getMountPathInfo(dst, conf).getTargetFs().getUri();\nif (!srcFs.equals(dstFs)) {\n  // cross-cluster: fall back to copy + delete\n  FileUtil.copy(...);\n}","typeGuard":"static boolean sameTargetCluster(FileSystem vfs, Path a, Path b,\n    Configuration conf) {\n  if (!(vfs instanceof ViewDistributedFileSystem)) return true;\n  ViewDistributedFileSystem v = (ViewDistributedFileSystem) vfs;\n  return v.getMountPathInfo(a, conf).getTargetFs().getUri()\n      .equals(v.getMountPathInfo(b, conf).getTargetFs().getUri());\n}","tryCatchPattern":"try {\n  vfs.rename(src, dst, Rename.OVERWRITE);\n} catch (HadoopIllegalArgumentException e) {\n  if (\"Can't rename across file systems.\".equals(e.getMessage())) {\n    copyThenDelete(src, dst); // non-atomic fallback\n  } else {\n    throw e;\n  }\n}","preventionTips":["Compare resolved mount targets for src/dst before any view-level rename","Use distcp for inter-cluster data moves; reserve view renames for same-mount paths"],"tags":["hdfs","viewfs","rename","federation"],"backgroundTag":"cross-filesystem-rename","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}