Skip to content

MultipartS3AsyncClient infers content type for single-part uploads but not multi-part uploads #6607

@mikewatt

Description

@mikewatt

Describe the bug

MultipartS3AsyncClient.putObject(r, body) will set the uploaded object's content type provided by body (if not explicitly provided as metadata) if the upload is performed as a single part upload, but not if the upload is performed as a multi part upload. This can be confusing as smaller uploaded objects have a content type set, and larger objects do not.

A similar scenario from 1.x: The SDK v1.x TransferManager class would fill in a missing content type for both single and multi part uploads.

Regression Issue

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

Expected Behavior

Consistent content-type behavior (either set equivalently or not set at all) regardless of upload size.

Current Behavior

A file under the multi-part threshold will have content-type set based on the detected file type; a file over the multi-part threshold will not have content-type set.

Reproduction Steps

    public void test() {
      var s3Client =
          S3AsyncClient.builder()
              .multipartEnabled(true)
              .multipartConfiguration(c -> c.thresholdInBytes(8L * 1024 * 1024))
              .forcePathStyle(true)
              .build();

      // Single part upload
      s3Client
          .putObject(
              r -> r.bucket(BUCKET).key("object1"), AsyncRequestBody.fromFile(new File("/tmp/video_5MB.mp4")))
          .join();

      // Multi part upload
      s3Client
          .putObject(
              r -> r.bucket(BUCKET).key("object2"), AsyncRequestBody.fromFile(new File("/tmp/video_10MB.mp4")))
          .join();

      {
        // Succeeds
        var md = s3Client.headObject(r -> r.bucket(BUCKET).key("object1")).join();
        assertThat(md.contentType()).isEqualTo("video/mp4");
      }

      {
        // Fails
        var md = s3Client.headObject(r -> r.bucket(BUCKET).key("object2")).join();
        assertThat(md.contentType()).isEqualTo("video/mp4");
      }
    }

Possible Solution

Content type appears to be set for single part uploads here: https://github.com/aws/aws-sdk-java-v2/blob/2.38.7/core/sdk-core/src/main/java/software/amazon/awssdk/core/runtime/transform/AsyncStreamingRequestMarshaller.java#L49-L51

Additional Information/Context

No response

AWS Java SDK version used

2.38.7

JDK version used

openjdk version "17.0.16"

Operating System and version

macOS 26.1

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