I have different objects that produce file that are saved in S3. Each object call the following function to save the file.
I have the following issue only with few objects. The objects either always save files or can never save the files.
/**
* Upload a file (with metadata).
*
* @param bucketId the id of the bucket
* @param key the key of the file
* @param inputStream the content of the file
* @param metadata the metadata of the file
* @return the eTag of the uploaded file
* @throws IOException If an error occurs during the file upload
*/
public String upload(String bucketId, String key, InputStream inputStream, Map<String, String> metadata) throws IOException {
LOG.info("Upload file {} on bucket {} with metadata: {}", key, bucketId, metadata);
CreateMultipartUploadRequest.Builder builder = CreateMultipartUploadRequest.builder();
if (!this.encryptionAlgorithm.equalsIgnoreCase("none")) {
builder = builder.serverSideEncryption(this.encryptionAlgorithm);
}
CreateMultipartUploadRequest createMultipartUploadRequest = builder.bucket(bucketId)
.key(key)
.metadata(metadata)
.build();
CreateMultipartUploadResponse createMultipartUploadResponse = s3Client.createMultipartUpload(createMultipartUploadRequest);
String uploadId = createMultipartUploadResponse.uploadId();
try {
List<CompletedPart> parts = uploadFileParts(bucketId, key, uploadId, inputStream);
CompleteMultipartUploadRequest completeMultipartUploadRequest = CompleteMultipartUploadRequest.builder()
.bucket(bucketId)
.key(key)
.uploadId(uploadId)
.multipartUpload(CompletedMultipartUpload.builder().parts(parts).build())
.build();
CompleteMultipartUploadResponse completeMultipartUploadResponse = s3Client.completeMultipartUpload(completeMultipartUploadRequest);
return completeMultipartUploadResponse.eTag();
} catch (Exception e) {
LOG.error("Error while uploading {} multipart {} on bucket {} with metadata {}", key, uploadId, bucketId, metadata, e);
s3Client.abortMultipartUpload(AbortMultipartUploadRequest.builder()
.bucket(bucketId)
.key(key)
.uploadId(uploadId)
.build());
throw e;
}
}
The error is
The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. For more information, see REST Authentication and SOAP Authentication for details. (Service: S3, Status Code: 403, Request ID: 79b6c0a2-0d74-1f30-a4bf-246e9631ccd8, Extended Request ID: null)
I verify, the bucket is always the same value, the input stream data contains the data of the file. The data are transmitted successfully to the S3 bucket. The key is always like eventsnapshot-21234-7-2021-08-12-1628767690000.jpg
.
Did you already had such of issue ?
I found the issue. If metadata value have a white space at the end, the signature generated by the AWS SDK will not be the same as the one returned by the server.
Probably that S3 trim the name and values of metadata.
Later I found also a similar issue in the aws-sdk-go: https://github.com/aws/aws-sdk-go/issues/2448
I'm using the version 2.15.36 of aws-sdk-java. I don't know if it was fixed in newer version of the SDK.