apache/hadoop · error · IllegalArgumentException

Copy destination must be different from source for %s.

Error message

Copy destination must be different from source for %s.

What it means

GoogleCloudStorage.copy throws IllegalArgumentException when source and destination resolve to the identical bucket AND identical object name. The connector treats a self-copy as a caller bug rather than a no-op or a way to mint a new generation. The check runs after the bucket location/storage-class checks and the non-empty object-name checkArguments.

Source

Thrown at hadoop-cloud-storage-project/hadoop-gcp/src/main/java/org/apache/hadoop/fs/gs/GoogleCloudStorage.java:854

        // TODO: Restrict this only when copy-with-rewrite is enabled
        if (!srcBucketInfo.getLocation().equals(dstBucketInfo.getLocation())) {
          throw new UnsupportedOperationException(
              "This operation is not supported across two different storage locations.");
        }

        if (!srcBucketInfo.getStorageClass().equals(dstBucketInfo.getStorageClass())) {
          throw new UnsupportedOperationException(
              "This operation is not supported across two different storage classes.");
        }
      }
      checkArgument(
          !isNullOrEmpty(source.getObjectName()), "srcObjectName must not be null or empty");
      checkArgument(
          !isNullOrEmpty(destination.getObjectName()), "dstObjectName must not be null or empty");
      if (srcBucketName.equals(dstBucketName)
          && source.getObjectName().equals(destination.getObjectName())) {
        throw new IllegalArgumentException(
            String.format(
                "Copy destination must be different from source for %s.",
                StringPaths.fromComponents(srcBucketName, source.getObjectName())));
      }
    }
  }

  private static GoogleCloudStorageItemInfo getGoogleCloudStorageItemInfo(
      GoogleCloudStorage gcsImpl,
      Map<StorageResourceId, GoogleCloudStorageItemInfo> bucketInfoCache,
      StorageResourceId resourceId)
      throws IOException {
    GoogleCloudStorageItemInfo storageItemInfo = bucketInfoCache.get(resourceId);
    if (storageItemInfo != null) {
      return storageItemInfo;
    }
    storageItemInfo = gcsImpl.getItemInfo(resourceId);
    bucketInfoCache.put(resourceId, storageItemInfo);

View on GitHub (pinned to 2add963021)

Solutions

  1. Guard the call: skip copy when src and dst bucket+object names are equal (usually a no-op for the caller's intent).
  2. Fix the code constructing the destination so it can never equal the source.
  3. If you genuinely need a fresh generation of the same object, copy to a temporary name then copy/delete back, or call the storage client's CopyRequest directly.

Example fix

// before
gcs.copy(srcId, dstId); // dstId.equals(srcId) -> IllegalArgumentException

// after
if (!srcId.equals(dstId)) {
  gcs.copy(srcId, dstId);
}
Defensive patterns

Strategy: validation

Validate before calling

if (srcId.getBucketName().equals(dstId.getBucketName())
    && srcId.getObjectName().equals(dstId.getObjectName())) {
  return; // self-copy is a no-op for this caller
}
gcs.copy(srcId, dstId);

Prevention

When it happens

Trigger: gcs.copy(source, destination) where srcBucketName.equals(dstBucketName) && source.getObjectName().equals(destination.getObjectName()) — e.g. rename fallbacks that compute dst from src, dedup logic, or scripts that pass the same path twice.

Common situations: Templated jobs where destination is derived from the source string and ends up identical; 'copy to backup' scripts invoked with the same src/dst arguments; rename implementations that fall back to copy without an equality guard.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/b632dba92b271e49. Report an issue: GitHub.