Skip to content

DefaultStsClient does not add error message from STS response to exception #6129

Open
@drnta

Description

@drnta

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

Metadata

Metadata

Assignees

Labels

guidanceQuestion that needs advice or information.third-partyThis issue is related to third-party libraries or applications.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions