Open
Description
Describe the bug
When using DefaultStsClient
the error mesage from STS response is not included in StsException if the Error
element is the root element in STS response.
Sample response from STS:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Error>
<Code>BadRequest</Code>
<Message>RoleArn must be at least 20 characters long</Message>
<Resource>/</Resource>
<RequestId>4a1c0e2eb20647b1</RequestId>
</Error>
Regression Issue
- Select this option if this issue appears to be a regression.
Expected Behavior
Error message from STS response is included in StsException
making it easier to understand the problem cause
Current Behavior
(Service: Sts, Status Code: 400, Request ID: 4a1c0e2eb20647b1) (SDK Attempt Count: 1)
software.amazon.awssdk.services.sts.model.StsException: (Service: Sts, Status Code: 400, Request ID: 4a1c0e2eb20647b1) (SDK Attempt Count: 1)
at software.amazon.awssdk.services.sts.model.StsException$BuilderImpl.build(StsException.java:113)
at software.amazon.awssdk.services.sts.model.StsException$BuilderImpl.build(StsException.java:61)
at software.amazon.awssdk.core.internal.http.pipeline.stages.utils.RetryableStageHelper.retryPolicyDisallowedRetryException(RetryableStageHelper.java:168)
at software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage.execute(RetryableStage.java:73)
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:53)
at software.amazon.awssdk.core.internal.http.StreamManagingStage.execute(StreamManagingStage.java:35)
at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallTimeoutTrackingStage.executeWithTimer(ApiCallTimeoutTrackingStage.java:82)
at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallTimeoutTrackingStage.execute(ApiCallTimeoutTrackingStage.java:62)
at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallTimeoutTrackingStage.execute(ApiCallTimeoutTrackingStage.java:43)
at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallMetricCollectionStage.execute(ApiCallMetricCollectionStage.java:50)
at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallMetricCollectionStage.execute(ApiCallMetricCollectionStage.java:32)
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:210)
at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.invoke(BaseSyncClientHandler.java:103)
at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.doExecute(BaseSyncClientHandler.java:173)
at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.lambda$execute$1(BaseSyncClientHandler.java:80)
at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.measureApiCallSuccess(BaseSyncClientHandler.java:182)
at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.execute(BaseSyncClientHandler.java:74)
at software.amazon.awssdk.core.client.handler.SdkSyncClientHandler.execute(SdkSyncClientHandler.java:45)
at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.execute(AwsSyncClientHandler.java:53)
at software.amazon.awssdk.services.sts.DefaultStsClient.assumeRole(DefaultStsClient.java:277)
at software.amazon.awssdk.services.sts.StsClient.assumeRole(StsClient.java:392)
Reproduction Steps
val stsClient = StsClient.builder()
.region(Region.EU_CENTRAL_1)
.endpointOverride(URI("<sts_host>"))
.credentialsProvider(
StaticCredentialsProvider.create(AwsBasicCredentials.create("<accessKeyId>", "<secretAccessKey>"))
)
.build()
val assumeRoleResponse = stsClient.assumeRole(
AssumeRoleRequest.builder()
.roleArn("short_arn")
.roleSessionName(randomUUID().toString())
.durationSeconds(10800)
.policy(
IamPolicy.create(
listOf(
IamStatement.builder()
.addPrincipal(IamPrincipal.ALL)
.effect(IamEffect.ALLOW)
.addAction("s3:ListBucket")
.addResource("arn:aws:s3:::bucket")
.addCondition(STRING_LIKE, "s3:prefix", "prefix")
.build()
)
).toJson()
)
.build()
)
Possible Solution
Method getErrorRoot
in AwsQueryProtocolFactory
may check if the document
itself is an Error
element.
/**
* Extracts the <Error/> element from the root XML document. Method is protected as EC2 has a slightly
* different location.
*
* @param document Root XML document.
* @return If error root is found than a fulfilled {@link Optional}, otherwise an empty one.
*/
Optional<XmlElement> getErrorRoot(XmlElement document) {
return "Error".equals(document.elementName()) ? Optional.of(document) : document.getOptionalElementByName("Error");
}
Additional Information/Context
No response
AWS Java SDK version used
2.29.52, 2.31.49
JDK version used
openjdk 21.0.7 2025-04-15 LTS
Operating System and version
Windows 11