You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Unable to use Java AWS SDK v2 to get object using SHA256 #4694
GetObjectResponse getObjectResponse = awsClient.getObject(
b -> b
.bucket(bucketName)
.key(key)
.checksumMode(ChecksumMode.ENABLED))
.response();
but MD5 checksum (and not SHA256) is applied instead, via this hard-coded reference this
and we're getting the exception: java.lang.IllegalStateException: Unexpected error creating MD5 checksum
note: headObject works fine
what are we missing?
thanks in advance
Expected Behavior
GetObject should work
Current Behavior
Getting an exception (see above)
Reproduction Steps
Please see the code in the bug description
Possible Solution
No response
Additional Information/Context
No response
AWS Java SDK version used
2.20.42
JDK version used
openjdk 11.0.14.1
Operating System and version
Linux service-5b7c8c4788-c62fp 5.4.238-148.347.amzn2.x86_64 #1 SMP Thu Apr 6 19:42:57 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
Caused by: java.lang.IllegalStateException: Unexpected error creating MD5 checksum
at software.amazon.awssdk.core.checksums.Md5Checksum.getDigest(Md5Checksum.java:63)
at software.amazon.awssdk.core.checksums.Md5Checksum.<init>(Md5Checksum.java:32)
at software.amazon.awssdk.services.s3.internal.handlers.SyncChecksumValidationInterceptor.modifyHttpResponseContent(SyncChecksumValidationInterceptor.java:74)
at software.amazon.awssdk.core.interceptor.ExecutionInterceptorChain.modifyHttpResponse(ExecutionInterceptorChain.java:148)
at software.amazon.awssdk.core.internal.http.pipeline.stages.AfterTransmissionExecutionInterceptorsStage.execute(AfterTransmissionExecutionInterceptorsStage.java:46)
at software.amazon.awssdk.core.internal.http.pipeline.stages.AfterTransmissionExecutionInterceptorsStage.execute(AfterTransmissionExecutionInterceptorsStage.java:28)
at software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(RequestPipelineBuilder.java:206)
at software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(RequestPipelineBuilder.java:206)
at software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(RequestPipelineBuilder.java:206)
at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallAttemptTimeoutTrackingStage.execute(ApiCallAttemptTimeoutTrackingStage.java:73)
at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallAttemptTimeoutTrackingStage.execute(ApiCallAttemptTimeoutTrackingStage.java:42)
at software.amazon.awssdk.core.internal.http.pipeline.stages.TimeoutExceptionHandlingStage.execute(TimeoutExceptionHandlingStage.java:78)
at software.amazon.awssdk.core.internal.http.pipeline.stages.TimeoutExceptionHandlingStage.execute(TimeoutExceptionHandlingStage.java:40)
at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallAttemptMetricCollectionStage.execute(ApiCallAttemptMetricCollectionStage.java:50)
at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallAttemptMetricCollectionStage.execute(ApiCallAttemptMetricCollectionStage.java:36)
at software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage.execute(RetryableStage.java:81)
at software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage.execute(RetryableStage.java:36)
at software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(RequestPipelineBuilder.java:206)
at software.amazon.awssdk.core.internal.http.StreamManagingStage.execute(StreamManagingStage.java:56)
at software.amazon.awssdk.core.internal.http.StreamManagingStage.execute(StreamManagingStage.java:36)
at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallTimeoutTrackingStage.executeWithTimer(ApiCallTimeoutTrackingStage.java:80)
at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallTimeoutTrackingStage.execute(ApiCallTimeoutTrackingStage.java:60)
at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallTimeoutTrackingStage.execute(ApiCallTimeoutTrackingStage.java:42)
at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallMetricCollectionStage.execute(ApiCallMetricCollectionStage.java:48)
at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallMetricCollectionStage.execute(ApiCallMetricCollectionStage.java:31)
at software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(RequestPipelineBuilder.java:206)
at software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(RequestPipelineBuilder.java:206)
at software.amazon.awssdk.core.internal.http.pipeline.stages.ExecutionFailureExceptionReportingStage.execute(ExecutionFailureExceptionReportingStage.java:37)
at software.amazon.awssdk.core.internal.http.pipeline.stages.ExecutionFailureExceptionReportingStage.execute(ExecutionFailureExceptionReportingStage.java:26)
at software.amazon.awssdk.core.internal.http.AmazonSyncHttpClient$RequestExecutionBuilderImpl.execute(AmazonSyncHttpClient.java:193)
at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.invoke(BaseSyncClientHandler.java:103)
at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.doExecute(BaseSyncClientHandler.java:171)
at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.lambda$execute$0(BaseSyncClientHandler.java:68)
at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.measureApiCallSuccess(BaseSyncClientHandler.java:179)
at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.execute(BaseSyncClientHandler.java:62)
at software.amazon.awssdk.core.client.handler.SdkSyncClientHandler.execute(SdkSyncClientHandler.java:52)
at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.execute(AwsSyncClientHandler.java:63)
at software.amazon.awssdk.services.s3.DefaultS3Client.getObject(DefaultS3Client.java:4535)
at software.amazon.awssdk.services.s3.S3Client.getObjectAsBytes(S3Client.java:8465)
at .......doGetObject(....java:322)
... 65 more
Caused by: java.security.NoSuchAlgorithmException: MD5 MessageDigest not available
at java.base/sun.security.jca.GetInstance.getInstance(GetInstance.java:159)
at java.base/java.security.MessageDigest.getInstance(MessageDigest.java:185)
at software.amazon.awssdk.core.checksums.Md5Checksum.getDigest(Md5Checksum.java:61)
The Java SDK will validate the MD5 checksum by default on GetObject. This is a client-side configuration, separate from the GetObject checksumMode option, and this is what the code in SyncChecksumValidationInterceptor is doing.
You can disable this default MD5 checksum validation in the S3 Client by setting a custom S3Configuration:
In this use-case, the SDK will automatically validate the SHA256 checksum on GetObject, after finishing reading the object. The SDK validates any of the 4 checksum types supported by the ChecksumAlgorithm in PutObject.
Ok, I took a step back and went through the question again. I also talked to the rest of the team about this issue.
Firstly, there is a known bug that I think is directly impacting you - we are performing both the default md5 checksum validation AND the checksumAlgorithm validation (SHA256 in your case) upon calling GetObject. We are going to change this to: if checksumMode is enabled on GetObject, we'll only perform the checksumAlgorithm validation, and not perform the md5 validation - the double validation is not necessary in this case.
While the fix for (1) is not released, as a workaround you can disable the md5 checksum in the s3 client by using the S3Configuration I showed in my previous comment -
To clarify: setting checksumValidationEnabled() to false will only disable the md5 checksum validation, not the SHA256 validation. The SHA256 checksum validation will still be performed if checksumMode is enabled in GetObject.
@gorell Will the fix of (1) address the issue you are reporting here? Is there anything else I'm missing?
Activity
gorell commentedon Nov 13, 2023
debora-ito commentedon Nov 13, 2023
@gorell can you share the full stacktrace of the error?
gorell commentedon Nov 14, 2023
@debora-ito here it is:
gorell commentedon Nov 14, 2023
@debora-ito just to clarify - we've customized our JDK to use SHA256 (and not MD5 which we don't support) for checksum
debora-ito commentedon Nov 15, 2023
The Java SDK will validate the MD5 checksum by default on GetObject. This is a client-side configuration, separate from the GetObject
checksumModeoption, and this is what the code inSyncChecksumValidationInterceptoris doing.You can disable this default MD5 checksum validation in the S3 Client by setting a custom S3Configuration:
gorell commentedon Nov 15, 2023
Got it @debora-ito , thank you. So is there a way to configure the GetObject validation to be SHA256? Given how the PutObject is configured.
debora-ito commentedon Nov 16, 2023
In this use-case, the SDK will automatically validate the SHA256 checksum on GetObject, after finishing reading the object. The SDK validates any of the 4 checksum types supported by the
ChecksumAlgorithmin PutObject.gorell commentedon Nov 16, 2023
But it looks like it does it with MD5, that's the reason I've opened this issue.
debora-ito commentedon Nov 16, 2023
Ok, I took a step back and went through the question again. I also talked to the rest of the team about this issue.
Firstly, there is a known bug that I think is directly impacting you - we are performing both the default md5 checksum validation AND the
checksumAlgorithmvalidation (SHA256 in your case) upon calling GetObject. We are going to change this to: ifchecksumModeis enabled on GetObject, we'll only perform thechecksumAlgorithmvalidation, and not perform the md5 validation - the double validation is not necessary in this case.While the fix for (1) is not released, as a workaround you can disable the md5 checksum in the s3 client by using the S3Configuration I showed in my previous comment -
To clarify: setting
checksumValidationEnabled()to false will only disable the md5 checksum validation, not the SHA256 validation. The SHA256 checksum validation will still be performed ifchecksumModeis enabled in GetObject.@gorell Will the fix of (1) address the issue you are reporting here? Is there anything else I'm missing?
gorell commentedon Nov 16, 2023
@debora-ito The answer to you question is 'yes', the fix of (1) will do the job, thank you very much
debora-ito commentedon Nov 16, 2023
Great, thank you for confirming.
I'll comment here once we have more updates on the fix.
debora-ito commentedon Dec 4, 2023
The fix is available in version
2.21.38.@gorell
kishd commentedon Aug 13, 2024
@debora-ito - This appears to be an issue with the delete api. "There is no way to disable MD5 for S3Client.deleteObjects because the service API requires the MD5 checksum". https://github.com/aws/aws-sdk-java-v2/blob/master/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/HttpChecksumStage.java