Skip to content

Duplicate HeadRequests against S3 Express when using the LegacyMD5Plugin. #6459

@ahmarsuhail

Description

@ahmarsuhail

Describe the bug

We're trying to upgrade S3A to SDK v2.32.23, see this PR. To restored third party support, we're adding the Md5 legacy plugin, like so:

   builder.addPlugin(LegacyMd5Plugin.create());

    // do not do request checksums as this causes third-party store problems.
    builder.requestChecksumCalculation(RequestChecksumCalculation.WHEN_REQUIRED);

    // response checksum validation. Slow, even with CRC32 checksums.
    if (parameters.isChecksumValidationEnabled()) {
      builder.responseChecksumValidation(ResponseChecksumValidation.WHEN_SUPPORTED);
    }

However, this is causing one of our ITests to fail:

  @Test
  public void testSDKMetricsCostOfGetFileStatusOnFile() throws Throwable {
    describe("Performing getFileStatus() on a file");
    Path simpleFile = file(methodPath());
    // and repeat on the file looking at AWS wired up stats
    final S3AFileSystem fs = getFileSystem();
    LOG.info("Initiating GET request for {}", simpleFile);
    verifyMetrics(() -> fs.getFileStatus(simpleFile),
        with(STORE_IO_REQUEST, 1));
  }

This test checks that only a single HTTP request is made, but we're seeing 2 requests, with the first request always failing when run against a S3 express store.

Things to note:

  • When making JUST a head request, this does not happen.
  • But when replicating what this test case does, I am able to replicate it. The test case will first check if a test/ directory exists, if it doesn't exist, it'll create it, and then do a HEAD.

If I comment out the .requestChecksumCalculation(RequestChecksumCalculation.WHEN_REQUIRED), there are no retries and the test passes.

Regression Issue

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

Expected Behavior

There should be no retries. Currently the first HEAD always fails with

2025-09-18 11:19:42,219 [setup] DEBUG http.wire (Wire.java:wire(73)) - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
2025-09-18 11:19:42,219 [setup] DEBUG http.wire (Wire.java:wire(73)) - http-outgoing-0 >> "[\r][\n]"
2025-09-18 11:19:42,220 [setup] DEBUG http.wire (Wire.java:wire(87)) - http-outgoing-0 << "end of stream"
2025-09-18 11:19:42,220 [setup] DEBUG conn.DefaultManagedHttpClientConnection (LoggingManagedHttpClientConnection.java:close(79)) - http-outgoing-0: Close connection

Current Behavior

HEAD request fails with end of stream and is retried.

Reproduction Steps

Run the below code exactly to reproduce locally. Making just a HEAD request will succeed. Something about this sequence of operations causes the retry. Everything works as expected when requestChecksumCalculation(RequestChecksumCalculation.WHEN_REQUIRED) is commented out.

public class TestClass {

    S3Client s3Client;

    public TestClass() {
        this.s3Client = S3Client.builder().region(Region.US_EAST_1)
                .addPlugin(LegacyMd5Plugin.create())
                .requestChecksumCalculation(RequestChecksumCalculation.WHEN_REQUIRED)
                .responseChecksumValidation(ResponseChecksumValidation.WHEN_SUPPORTED)
                .overrideConfiguration(o -> o.retryStrategy(b -> b.maxAttempts(1)))
                .build();
    }


    public void testS3Express(String bucket, String key) {
        s3Client.listObjectsV2(ListObjectsV2Request.builder()
                .bucket("s3-express-bucket")
                .maxKeys(2)
                .prefix("test/")
                .build());


        try {
            s3Client.headObject(HeadObjectRequest.builder().bucket("s3-express-bucket")
                    .key("test")
                    .build());
        } catch (Exception e) {
            System.out.println("Exception thrown: " + e.getMessage());
        }

        s3Client.putObject(PutObjectRequest
                .builder()
                .bucket("s3-express-bucket")
                .key("test/").build(), RequestBody.empty());

        s3Client.headObject(HeadObjectRequest.builder().bucket("s3-express-bucket")
                .key("<KEY>")
                .build());
    }

}

Possible Solution

No response

Additional Information/Context

No response

AWS Java SDK version used

2.32.23

JDK version used

17

Operating System and version

Amazon linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis issue is a bug.p2This is a standard priority issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions