{"record":{"id":"bf480b97251b08ef","repo":"apache/hadoop","slug":"this-operation-is-not-supported-across-two-differe","errorCode":null,"errorMessage":"This operation is not supported across two different buckets.","messagePattern":"This operation is not supported across two different buckets\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hadoop-cloud-storage-project/hadoop-gcp/src/main/java/org/apache/hadoop/fs/gs/GoogleCloudStorage.java","lineNumber":721,"sourceCode":"   * Preconditions} in addition to checking for src/dst bucket equality.\n   */\n  static void validateMoveArguments(\n      Map<StorageResourceId, StorageResourceId> sourceToDestinationObjectsMap) throws IOException {\n    checkNotNull(sourceToDestinationObjectsMap, \"srcObjects must not be null\");\n\n    if (sourceToDestinationObjectsMap.isEmpty()) {\n      return;\n    }\n\n    for (Map.Entry<StorageResourceId, StorageResourceId> entry :\n        sourceToDestinationObjectsMap.entrySet()) {\n      StorageResourceId source = entry.getKey();\n      StorageResourceId destination = entry.getValue();\n      String srcBucketName = source.getBucketName();\n      String dstBucketName = destination.getBucketName();\n      // Avoid move across buckets.\n      if (!srcBucketName.equals(dstBucketName)) {\n        throw new UnsupportedOperationException(\n            \"This operation is not supported across two different buckets.\");\n      }\n      checkArgument(\n          !isNullOrEmpty(source.getObjectName()), \"srcObjectName must not be null or empty\");\n      checkArgument(\n          !isNullOrEmpty(destination.getObjectName()), \"dstObjectName must not be null or empty\");\n      if (srcBucketName.equals(dstBucketName)\n          && source.getObjectName().equals(destination.getObjectName())) {\n        throw new IllegalArgumentException(\n            String.format(\n                \"Move destination must be different from source for %s.\",\n                StringPaths.fromComponents(srcBucketName, source.getObjectName())));\n      }\n    }\n  }\n\n  void copy(Map<StorageResourceId, StorageResourceId> sourceToDestinationObjectsMap)\n      throws IOException {","sourceCodeStart":703,"sourceCodeEnd":739,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-gcp/src/main/java/org/apache/hadoop/fs/gs/GoogleCloudStorage.java#L703-L739","documentation":"The move (rename) validation loop rejects any source/destination pair whose bucket names differ, throwing UnsupportedOperationException(\"This operation is not supported across two different buckets.\"). The connector implements move as a same-bucket metadata operation (copy + delete); a cross-bucket move would require cross-bucket rewriting, which it deliberately does not attempt.","triggerScenarios":"fs.rename() (or GoogleCloudStorage move API) with src and dst on different buckets — e.g. renaming gs://bucketA/dir into gs://bucketB/dir. Fails during argument validation before any service call.","commonSituations":"Distcp or job config placing work and output dirs on different buckets and then renaming between them; scripts assuming POSIX rename works across mounts; porting code from another connector that allowed cross-bucket rename.","solutions":["Perform copy-then-delete explicitly for cross-bucket moves (gcs.copy supports cross-bucket under conditions)","Keep rename source and destination inside the same bucket","Restructure the pipeline so intermediate data lives in the destination bucket"],"exampleFix":"// before\nfs.rename(new Path(\"gs://bucketA/src\"), new Path(\"gs://bucketB/dst\"));\n// -> UnsupportedOperationException: across two different buckets\n\n// after\nFileSystem srcFs = ...; // bucketA\nsrcFs.rename(new Path(\"gs://bucketA/src\"), new Path(\"gs://bucketA/dst\")); // intra-bucket only\n// for cross-bucket: FileUtil.copy(srcFs, srcPath, dstFs, dstPath, true, conf);","handlingStrategy":"validation","validationCode":"// Guard renames: same bucket only\nif (!srcPath.toUri().getHost().equals(dstPath.toUri().getHost())) {\n  throw new UnsupportedOperationException(\"cross-bucket rename not allowed; use copy+delete\");\n}\nfs.rename(srcPath, dstPath);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Design pipelines so renames stay within one bucket","Use FileUtil.copy + delete for deliberate cross-bucket moves","Validate bucket hosts on all path pairs before bulk rename loops"],"tags":["gcs","hadoop-gcp","rename","cross-bucket","unsupported-operation"],"backgroundTag":"cross-bucket-operation-rejected","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}