-
Suggestion
-
Resolution: Unresolved
-
None
-
None
-
0
-
2
-
Issue Summary
Jira Data Center can store avatars and attachments in Amazon S3 (AWS). As a Jira administrator, I would like to use Dell ECS Enterprise Object Storage to store avatars and attachments. This is a third-party appliance that exposes an S3-compatible interface. Currently, Atlassian only officially supports Amazon S3.
Steps to Reproduce
- Connect Jira DC to ECS, following the instructions:
Expected Results
Jira DC stores and retrieves avatars and attachments as designed. All health checks pass.
Actual Results
Errors are logged to the atlassian-jira.log file, and avatars/attachments fail to save.
Startup:
2025-01-08 16:00:00,000-0000 JIRA-Bootstrap WARN [c.a.jira.health.HealthChecks] Unable to connect to the avatar and attachment storage. 2025-01-08 16:00:00,000-0000 JIRA-Bootstrap WARN [c.a.jira.health.HealthChecks] The Content-SHA256 you specified did not match what we received (Service: S3, Status Code: 400, Request ID: ..., Extended Request ID: ...)
During the health check job:
2025-01-08 16:00:00,000-0000 Caesium-1-1 WARN [c.a.t.healthcheck.concurrent.SupportHealthCheckProcess] Health check 'Avatar Storage' failed with severity 'warning': 'Unable to write to avatar storage.' 2025-01-08 16:00:00,000-0000 Caesium-1-1 ERROR [c.a.t.healthcheck.concurrent.SupportHealthCheckProcess] Health check 'Attachment Storage' failed with severity 'major': 'Unable to write to attachment storage.'
When attempting to upload an avatar (or attachment):
2025-01-08 16:00:00,000-0000 http-nio-8080-exec-1 ERROR user 1x1x1 abcdef 0.0.0.0 /rest/api/latest/user/avatar [c.a.jira.avatar.AvatarPickerHelperImpl] Unable to create avatar. com.atlassian.dc.filestore.api.exception.FileStoreAccessDeniedException: The Content-SHA256 you specified did not match what we received (Service: S3, Status Code: 400, Request ID: ..., Extended Request ID: ...) at com.atlassian.dc.filestore.impl.s3.OperationExecutorImpl.performOperation(OperationExecutorImpl.java:46) at com.atlassian.dc.filestore.impl.s3.S3Path.put(S3Path.java:232) at com.atlassian.dc.filestore.api.FileStore$Writer.write(FileStore.java:336) at com.atlassian.dc.filestore.api.FileStore$Writer.write(FileStore.java:351) at com.atlassian.jira.avatar.AvatarManagerImpl.processImage(AvatarManagerImpl.java:290) at com.atlassian.jira.avatar.AvatarManagerImpl.create(AvatarManagerImpl.java:167) at com.atlassian.jira.avatar.AvatarPickerHelperImpl.convertTemporaryToReal(AvatarPickerHelperImpl.java:170) [trimmed Spring resolution] at jdk.proxy156/jdk.proxy156.$Proxy2932.convertTemporaryToReal(Unknown Source) at com.atlassian.jira.rest.v2.issue.AvatarResourceHelper.createAvatarFromTemporary(AvatarResourceHelper.java:194) at com.atlassian.jira.rest.v2.issue.UserResource.createAvatarFromTemporary(UserResource.java:1131) [trimmed Servlet filters] Caused by: java.util.concurrent.CompletionException: software.amazon.awssdk.services.s3.model.S3Exception: The Content-SHA256 you specified did not match what we received (Service: S3, Status Code: 400, Request ID: ..., Extended Request ID: ...) at software.amazon.awssdk.utils.CompletableFutureUtils.errorAsCompletionException(CompletableFutureUtils.java:64) at software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncExecutionFailureExceptionReportingStage.lambda$execute$0(AsyncExecutionFailureExceptionReportingStage.java:51) at java.base/java.util.concurrent.CompletableFuture.uniHandle(Unknown Source) at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(Unknown Source) at java.base/java.util.concurrent.CompletableFuture.postComplete(Unknown Source) at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(Unknown Source) at software.amazon.awssdk.utils.CompletableFutureUtils.lambda$forwardExceptionTo$0(CompletableFutureUtils.java:78) at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(Unknown Source) at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(Unknown Source) at java.base/java.util.concurrent.CompletableFuture.postComplete(Unknown Source) at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(Unknown Source) at software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncRetryableStage2$RetryingExecutor.maybeAttemptExecute(AsyncRetryableStage2.java:135) at software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncRetryableStage2$RetryingExecutor.maybeRetryExecute(AsyncRetryableStage2.java:152) at software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncRetryableStage2$RetryingExecutor.lambda$attemptExecute$1(AsyncRetryableStage2.java:123) at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(Unknown Source) at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(Unknown Source) at java.base/java.util.concurrent.CompletableFuture.postComplete(Unknown Source) at java.base/java.util.concurrent.CompletableFuture.complete(Unknown Source) at software.amazon.awssdk.core.internal.http.pipeline.stages.MakeAsyncHttpRequestStage.lambda$execute$0(MakeAsyncHttpRequestStage.java:110) at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(Unknown Source) at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(Unknown Source) at java.base/java.util.concurrent.CompletableFuture.postComplete(Unknown Source) at java.base/java.util.concurrent.CompletableFuture.complete(Unknown Source) at software.amazon.awssdk.core.internal.http.pipeline.stages.MakeAsyncHttpRequestStage.completeResponseFuture(MakeAsyncHttpRequestStage.java:253) at software.amazon.awssdk.core.internal.http.pipeline.stages.MakeAsyncHttpRequestStage.lambda$executeHttpRequest$3(MakeAsyncHttpRequestStage.java:167) at java.base/java.util.concurrent.CompletableFuture.uniHandle(Unknown Source) at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(Unknown Source) at java.base/java.util.concurrent.CompletableFuture$Completion.run(Unknown Source) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ... 1 more Caused by: software.amazon.awssdk.services.s3.model.S3Exception: The Content-SHA256 you specified did not match what we received (Service: S3, Status Code: 400, Request ID: ..., Extended Request ID: ...) at software.amazon.awssdk.protocols.xml.internal.unmarshall.AwsXmlPredicatedResponseHandler.handleErrorResponse(AwsXmlPredicatedResponseHandler.java:156) at software.amazon.awssdk.protocols.xml.internal.unmarshall.AwsXmlPredicatedResponseHandler.handleResponse(AwsXmlPredicatedResponseHandler.java:108) at software.amazon.awssdk.protocols.xml.internal.unmarshall.AwsXmlPredicatedResponseHandler.handle(AwsXmlPredicatedResponseHandler.java:85) at software.amazon.awssdk.protocols.xml.internal.unmarshall.AwsXmlPredicatedResponseHandler.handle(AwsXmlPredicatedResponseHandler.java:43) at software.amazon.awssdk.core.internal.handler.BaseClientHandler.lambda$successTransformationResponseHandler$7(BaseClientHandler.java:279) at software.amazon.awssdk.core.internal.http.async.AsyncResponseHandler.lambda$prepare$0(AsyncResponseHandler.java:92) at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(Unknown Source) at java.base/java.util.concurrent.CompletableFuture.postComplete(Unknown Source) at java.base/java.util.concurrent.CompletableFuture.complete(Unknown Source) at software.amazon.awssdk.core.internal.http.async.AsyncResponseHandler$BaosSubscriber.onComplete(AsyncResponseHandler.java:135) at software.amazon.awssdk.core.internal.metrics.BytesReadTrackingPublisher$BytesReadTracker.onComplete(BytesReadTrackingPublisher.java:74) at software.amazon.awssdk.utils.async.SimplePublisher.doProcessQueue(SimplePublisher.java:275) at software.amazon.awssdk.utils.async.SimplePublisher.processEventQueue(SimplePublisher.java:224) at software.amazon.awssdk.utils.async.SimplePublisher.complete(SimplePublisher.java:157) at java.base/java.util.concurrent.CompletableFuture.uniRunNow(Unknown Source) at java.base/java.util.concurrent.CompletableFuture.uniRunStage(Unknown Source) at java.base/java.util.concurrent.CompletableFuture.thenRun(Unknown Source) at software.amazon.awssdk.services.s3.internal.crt.S3CrtResponseHandlerAdapter.onErrorResponseComplete(S3CrtResponseHandlerAdapter.java:200) at software.amazon.awssdk.services.s3.internal.crt.S3CrtResponseHandlerAdapter.handleError(S3CrtResponseHandlerAdapter.java:179) at software.amazon.awssdk.services.s3.internal.crt.S3CrtResponseHandlerAdapter.onFinished(S3CrtResponseHandlerAdapter.java:148) at software.amazon.awssdk.crt.s3.S3MetaRequestResponseHandlerNativeAdapter.onFinished(S3MetaRequestResponseHandlerNativeAdapter.java:25)
Atlassian Support understands this because ECS implements the S3 API differently, requiring special accommodations.
Workaround
Currently, there is no known workaround for this behavior. A workaround will be added here when available.
- is caused by
-
JRASERVER-36892 Add support for distributed object store via Amazon S3 API for storing JIRA attachments
- Waiting for Release
- is cloned from
-
JRASERVER-73700 Add support for MS Azure Blob Storage for Jira
- Gathering Interest
- is related to
-
JRASERVER-78550 Add support to COS on other than AWS cloud providers
- Gathering Interest