Skip to content

Copying large S3 objects from versioning enabled buckets requires s3:GetObjectVersion permission #7117

Description

@kurtismash

Describe the bug

Copying S3 objects larger than 8 MiB the from versioning enabled buckets now requires s3:GetObjectVersion permission.

Regression Issue

  • Select this option if this issue appears to be a regression.

Expected Behavior

When no sourceVersionId is given in the method call, no versionId should be included in the API requests to AWS.

Current Behavior

The API requests to AWS include a versionId parameter, meaning that s3:GetObjectVersion permission is required.

Reproduction Steps

Using a principal who has s3:GetObject but not s3:GetObjectVersion permission attempt to copy a large object in S3 from a versioning enabled bucket.

package com.example.s3copy;

import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.model.CopyObjectRequest;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.CompletedCopy;
import software.amazon.awssdk.transfer.s3.model.Copy;
import software.amazon.awssdk.transfer.s3.model.CopyRequest;

public class S3MultipartCopy {

    public static void main(String[] args) {
        if (args.length < 4) {
            System.err.println("Usage: S3MultipartCopy <sourceBucket> <sourceKey> <destBucket> <destKey> [region]");
            System.exit(1);
        }

        String sourceBucket = args[0];
        String sourceKey    = args[1];
        String destBucket   = args[2];
        String destKey      = args[3];
        Region region       = args.length >= 5 ? Region.of(args[4]) : Region.US_EAST_1;

        System.out.printf("Copying s3://%s/%s  →  s3://%s/%s (region: %s)%n",
                sourceBucket, sourceKey, destBucket, destKey, region);

        // The CRT-based async client enables multipart copy automatically
        S3AsyncClient crtClient = S3AsyncClient.crtBuilder()
                .region(region)
                .targetThroughputInGbps(10.0)
                .minimumPartSizeInBytes(8 * 1024 * 1024L) // 8 MB minimum part size
                .build();

        try (S3TransferManager transferManager = S3TransferManager.builder()
                .s3Client(crtClient)
                .build()) {
            CopyObjectRequest copyObjectRequest = CopyObjectRequest.builder()
                    .sourceBucket(sourceBucket)
                    .sourceKey(sourceKey)
                    .destinationBucket(destBucket)
                    .destinationKey(destKey)
                    .build();
            CopyRequest copyRequest = CopyRequest.builder()
                    .copyObjectRequest(copyObjectRequest)
                    .build();
            Copy copy = transferManager.copy(copyRequest);
            CompletedCopy result = copy.completionFuture().join();

            System.out.println("Copy complete!");
            System.out.println("ETag: " + result.response().copyObjectResult().eTag());

        } finally {
            crtClient.close();
        }
    }
}

Possible Solution

Looks to be a regression introduced to services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/multipart/CopyObjectHelper.java in ea79934, where the versionId is now always included in the copy request if returned by the head object call.

Additional Information/Context

No response

AWS Java SDK version used

2.47.1

JDK version used

openjdk version "25.0.3" 2026-04-21

Operating System and version

Ubuntu 24.04.4 LTS

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis issue is a bug.p1This is a high priority issuepotential-regressionMarking this issue as a potential regression to be checked by team member

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions