Skip to content

AWS: Add chunked encoding configuration for S3 requests#15242

Merged
singhpk234 merged 13 commits intoapache:mainfrom
plusplusjiajia:add-s3-config
Apr 5, 2026
Merged

AWS: Add chunked encoding configuration for S3 requests#15242
singhpk234 merged 13 commits intoapache:mainfrom
plusplusjiajia:add-s3-config

Conversation

@plusplusjiajia
Copy link
Copy Markdown
Member

@plusplusjiajia plusplusjiajia commented Feb 6, 2026

@github-actions github-actions bot added the AWS label Feb 6, 2026
@steveloughran
Copy link
Copy Markdown
Contributor

  • what about a test which actually enables it, such as TestS3MultipartUpload?
  • documentation

@steveloughran
Copy link
Copy Markdown
Contributor

Actually, I've just noticed that org.apache.iceberg.aws.s3.signer.S3V4RestSignerClient doesn't support chunked encoding.

Until that's in, RestCatalog access via S3FileIO isn't going to work.

It'd be OK for direct S3 IO though

@plusplusjiajia
Copy link
Copy Markdown
Member Author

  • what about a test which actually enables it, such as TestS3MultipartUpload?
  • documentation

Thanks for you advises, I've added testMultipartUploadWithChunkedEncoding, lease help me take a look, thanks!

Copy link
Copy Markdown
Contributor

@steveloughran steveloughran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commented

test looks good -I always test against real S3 stores so it's nice to see a unit test pushing up a few MB without problems.

*/
public static final String CHUNKED_ENCODING_ENABLED = "s3.chunked-encoding-enabled";

public static final boolean CHUNKED_ENCODING_ENABLED_DEFAULT = true;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this must be false by default because org.apache.iceberg.aws.s3.signer.S3V4RestSignerClient will not sign chunked encoding operations.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this must be false by default because org.apache.iceberg.aws.s3.signer.S3V4RestSignerClient will not sign chunked encoding operations.

Thanks! done.

Copy link
Copy Markdown
Contributor

@steveloughran steveloughran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks. My concerns are all addressed.

Afraid you now need to await a review by an iceberg committer

@plusplusjiajia
Copy link
Copy Markdown
Member Author

@amogh-jahagirdar could you help to review this pr?

Copy link
Copy Markdown
Contributor

@JingsongLi JingsongLi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

@JingsongLi
Copy link
Copy Markdown
Contributor

@singhpk234 @huaxingao Can you help us take a look? Just added a configuration.

- `s3.session-token`: if present, this value should be used for as the session token
- `s3.remote-signing-enabled`: if `true` remote signing should be performed as described in the `s3-signer-open-api.yaml` specification
- `s3.cross-region-access-enabled`: if `true`, S3 Cross-Region bucket access is enabled
- `s3.chunked-encoding-enabled`: if `true`, chunked encoding is enabled for S3 requests
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want rest catalogs to returns this ? for now can this a client side catalog property ?

Copy link
Copy Markdown
Member Author

@plusplusjiajia plusplusjiajia Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want rest catalogs to returns this ? for now can this a client side catalog property ?

Yes, when the server returns storage credentials, the related S3 properties are expected to be applied in S3FileIO directly, the client doesn't need to be aware of or manage S3-specific configurations on its own.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

purely client side; all that comes back from the catalog is signed access to a single file and a header to say cache/no-no cache. Now, that's not enough to deal with SSE-C encryption where you'd need to say (encryption: SSE-C, secret="...."), but that's OK because SSE-C is an utter management nightmare and everyone uses SSE-KMS. Which doesn't need any information from the catalog.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

purely client side; all that comes back from the catalog is signed access to a single file and a header to say cache/no-no cache. Now, that's not enough to deal with SSE-C encryption where you'd need to say (encryption: SSE-C, secret="...."), but that's OK because SSE-C is an utter management nightmare and everyone uses SSE-KMS. Which doesn't need any information from the catalog.

makes sense, i will remove it, thanks for the advise!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want rest catalogs to returns this ? for now can this a client side catalog property ?

Agreed, keep this as a client-side catalog property. I've removed the change.

Comment on lines +175 to +176
assertThat(testIo.newInputFile(testObjectUri).getLength())
.isEqualTo(parts * (long) S3FileIOProperties.MULTIPART_SIZE_MIN);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wonder if we can also assert that contents of files are correct ?

Copy link
Copy Markdown
Contributor

@steveloughran steveloughran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commented. I'm making that new test stricter on the basis you've done most of the work and it's good to round off.

FWIW we once hit a prefetch bug in abfs client where under specific race conditions you could get a block from another stream in the same process. This test wouldn't replicate that condition either (2+ GB files, multiple readers, etc), but it'd be a bit stricter.

verifyInts(testIo, intObjectUri, () -> expectedInt);

// Verify write and read with bytes
byte expectedByte = 42;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice test, but it this doesn't detect parts committed out of order. What incrementing the expectedByte with each part and validating on the same ranges?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice test, but it this doesn't detect parts committed out of order. What incrementing the expectedByte with each part and validating on the same ranges?

Good point! I've updated the test.

Copy link
Copy Markdown
Contributor

@steveloughran steveloughran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the changes. Lost a weekend to a good horror story with a prefetch race condition that shipped. validation of test payloads weren't enough, that payload had to be a 2+GB + CSV file, but still, every safety check helps

https://issues.apache.org/jira/browse/HADOOP-18521

Copy link
Copy Markdown
Contributor

@singhpk234 singhpk234 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks @plusplusjiajia

can you please double confirm the integ tests pass ? asking because they are not run as part of CI

@plusplusjiajia
Copy link
Copy Markdown
Member Author

LGTM, thanks @plusplusjiajia

can you please double confirm the integ tests pass ? asking because they are not run as part of CI

Thanks for the reminder, I've verified them manually.

@JingsongLi
Copy link
Copy Markdown
Contributor

Hi @steveloughran , can you take a look again, do you have any other concerns?

@steveloughran
Copy link
Copy Markdown
Contributor

I have no concerns but I'm not a committer. I'll give a finall review and mark if I'm happy with it, but you'll need approval from an iceberg committer.

Comment on lines +306 to +308
public static final String CHUNKED_ENCODING_ENABLED = "s3.chunked-encoding-enabled";

public static final boolean CHUNKED_ENCODING_ENABLED_DEFAULT = false;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry for the last moment, seems like SDK default is true ? if yes this might be different than what we have been doing so far ? i wonder if we should just pass it to builder if the above propery is not empty and not have defaults ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@singhpk234 the CatalogSigner doesn't sign chunked encoding
L255

    if (signerParams.enableChunkedEncoding()) {
      throw new UnsupportedOperationException("Chunked encoding not supported");
    }

Setting it to false ensures that if a client is using it to sign for uploads (polaris are working on/have done that) then the requests are being signed.
It's likely a failure condition which hasn't yet been encountered

@adutra

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree for those scenarios we can prompt user to disable it themselves. The way I am approaching is lets say iceberg v 1.10 shipped with chunked encoding true, 1.11 will be shipping ti for false ? this can be regression for no signing use cases ? Hence the recommendation to keep the sdk default but at the same time give ways to override these, wdyt

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree for those scenarios we can prompt user to disable it themselves. The way I am approaching is lets say iceberg v 1.10 shipped with chunked encoding true, 1.11 will be shipping ti for false ? this can be regression for no signing use cases ? Hence the recommendation to keep the sdk default but at the same time give ways to override these, wdyt

Thanks for the feedback @singhpk234, that's a fair point. Changing the default to false would indeed be a regression for users who don't use the REST catalog signer.

@steveloughran I agree the CatalogSigner incompatibility is a real concern, but I think we can address it without changing the SDK default for everyone. Users who rely on CatalogSigner can explicitly set
s3.chunked-encoding-enabled=false, and we can document this clearly. This way we avoid a silent performance regression for the majority of users while still providing a clear path for signing use cases.

I'll update the PR to keep the default as true.

public void testMultipartUploadWithChunkedEncoding(boolean chunkedEncodingEnabled)
throws IOException {
// Create a new S3FileIO with specified chunked encoding setting
S3FileIO testIo = new S3FileIO(() -> s3);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we wrap with try-with resource , so the testIO is closed ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we wrap with try-with resource , so the testIO is closed ?

Thanks for the catch! Updated to use try-with-resources to ensure testIo is properly closed.

@singhpk234 singhpk234 merged commit ec2de91 into apache:main Apr 5, 2026
36 checks passed
@singhpk234
Copy link
Copy Markdown
Contributor

Thanks for the change @plusplusjiajia ! Thanks for review @JingsongLi @steveloughran !

@plusplusjiajia
Copy link
Copy Markdown
Member Author

Thank you all for taking the time to review this PR!

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants