🧑‍✈️

S3互換Objest Storageを使っている場合、SDK for Java 2.xを2.30.0以上にversion upする時は要注意

2025/02/08に公開

TL;DR

S3には次のようなData Integrity Protectionsの仕組みがあります。
https://docs.aws.amazon.com/sdkref/latest/guide/feature-dataintegrity.html

この仕組みが、SDK for Java 2.xの2.30.0より自動で有効化されるようになりました。
https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/s3-checksums.html

もしも使っているS3互換Object Storageがコレに対応していない場合、Object Storageへのリクエストがエラーとなる可能性があります。
(testをちゃんと書いていれば気付けると思いますが、少し注意してversion upするといいでしょう)

遭遇した場合は次のような設定をしましょう。

// sync clientの場合
S3Client
    .builder()
    // ...
    .requestChecksumCalculation(RequestChecksumCalculation.WHEN_REQUIRED) // これ
    .responseChecksumValidation(ResponseChecksumValidation.WHEN_REQUIRED) // これ
    // ...
    .build()

// async clientの場合
S3AsyncClient
    .builder()
    // ...
    .requestChecksumCalculation(RequestChecksumCalculation.WHEN_REQUIRED) // これ
    .responseChecksumValidation(ResponseChecksumValidation.WHEN_REQUIRED) // これ
    // ...
    .build()

きっかけ

software.amazon.awssdk:s32.30.0以上にあげたところ、社内で使用しているS3互換Object Storageで以下のようなエラーが発生するようになりました。

(Service: S3, Status Code: 400, Request ID: MASKED...)
software.amazon.awssdk.services.s3.model.S3Exception:  (Service: S3, Status Code: 400, Request ID: MASKED...)
    at software.amazon.awssdk.protocols.xml.internal.unmarshall.AwsXmlPredicatedResponseHandler.handleErrorResponse(AwsXmlPredicatedResponseHandler.java:155)
...

原因

S3には次のようなData Integrity Protectionsの仕組みがあります。
https://docs.aws.amazon.com/sdkref/latest/guide/feature-dataintegrity.html

ざっくりという仕組みを解説すると、

  • S3へuploadするときにコンテンツのchecksumを計算し、コンテンツと一緒にchecksumもuploadします
    • S3 server側にて送信されたコンテンツのchecksum検証をします
  • S3からコンテンツをdownloadするときに、コンテンツと一緒にchecksumもdownloadします
    • SDK側で受信したコンテンツのchecksum検証をします

(もともと、upload時にContent-MD5ヘッダーを指定することでデータ完全性の確認をする機能もありましたが、これの上位互換的なものでしょうか。downloadでもデータ完全性の確認ができるようになったのは便利ですね)

この仕組みが、2.30.0より自動で有効化されるようになりました。
https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/s3-checksums.html

が、自分が使っているS3互換Object Storageでは対応されていなかったため、エラーが発生するようになってしまったというわけです。

自分の場合はtestですぐに気付けていたのですが、マイナーバージョンしか変わっていないため、油断してしまう人も多いのかなと思います。

各S3互換Object Storageの対応状況

ちゃんと調べたかったけど、諦めました!

雑にo1 pro mode & Deep Searchに調べさせた結果だと、MinIO対応しているが、他のものは対応していないそう。

この仕組みが導入されたのが2022年2月と比較的新しい(といっても3年前)ため、あまり対応はされていないでしょうね。
https://aws.amazon.com/jp/blogs/aws/new-additional-checksum-algorithms-for-amazon-s3/

余談

SDK for Java 1.xでは未だにこの機能に対応していないため、こういった問題には遭遇しません。が、今年中にEOLを迎えるので、まだ2.x系に移行できていない人はあげておきましょう。
https://aws.amazon.com/jp/blogs/developer/announcing-end-of-support-for-aws-sdk-for-java-v1-x-on-december-31-2025/

Discussion