Summary
Starting in AWS SDK for Java v2.47.0, auth scheme resolution and endpoint resolution have moved from per-service generated interceptors to shared pipeline stages in sdk-core. This fixes a bug where credentials injected via interceptors were ignored (#6486) and establishes clear separation between customer extension points (interceptors) and SDK internals.
What Changed
RESOLVED_ENDPOINT in execution attributes is now null during interceptor execution (modifyRequest() / modifyHttpRequest()). Endpoint resolution happens after interceptors complete.
SELECTED_AUTH_SCHEME in execution attributes contains a placeholder during interceptor execution. Auth scheme resolution happens after interceptors complete.
- The HTTP request host/URL in
modifyHttpRequest() is the base service endpoint, not the fully resolved endpoint. For example, S3 requests will show s3.region.amazonaws.com instead of bucket.s3.region.amazonaws.com at that point.
Who Is Affected
Most users are not affected. This change should be transparent for standard SDK usage.
You may be affected if your code:
- Reads
SdkInternalExecutionAttribute.RESOLVED_ENDPOINT during modifyRequest() or modifyHttpRequest() . It will now be null at that point.
- Reads
SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME during interceptor execution. It will contain a placeholder.
- Reads the HTTP request host/URL in
modifyHttpRequest() expecting the fully resolved endpoint (e.g., bucket.s3.region.amazonaws.com). Endpoint resolution has not happened yet at that point, so the host will be the base service endpoint.
Note: SdkInternalExecutionAttribute is an internal API. Backward compatibility is not guaranteed for internal attributes.
Bug Fix
Credentials injected via ExecutionInterceptor.modifyRequest() (through AwsRequestOverrideConfiguration.credentialsProvider()) are now correctly used for signing. Previously they were ignored because auth scheme resolution happened before interceptors ran.
Migration Guide
Reading the resolved endpoint or auth scheme
Use beforeTransmission(). Both endpoint resolution and auth scheme resolution are complete at that point:
@Override
public void beforeTransmission(Context.BeforeTransmission context, ExecutionAttributes attrs) {
// Resolved endpoint URL
URI resolvedUrl = context.httpRequest().getUri();
}
Overriding the endpoint
Modify the HTTP request URL directly in modifyHttpRequest(). The pipeline detects the modification and preserves it:
@Override
public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context, ExecutionAttributes attrs) {
URI destination = URI.create(myEndpoint);
return context.httpRequest().toBuilder()
.protocol(destination.getScheme())
.host(destination.getHost())
.port(destination.getPort())
.build();
}
Custom signer
Register via putAuthScheme() at client build time instead of manipulating SELECTED_AUTH_SCHEME in an interceptor:
client = ServiceClient.builder()
.putAuthScheme(new MyCustomAuthScheme())
.build();
For full examples on implementing custom auth schemes, see the AuthScheme javadoc.
Version Compatibility
If you run into NoClassDefFoundError, NoSuchMethodError, or cannot find symbol errors after upgrading, make sure all SDK dependencies are on the same version. We recommend using the BOM to manage SDK dependencies:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bom</artifactId>
<version>2.x.y</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Why We Made This Change
The SDK was using ExecutionInterceptor for internal auth/endpoint resolution, but this interface was designed for customer extensibility. This caused ordering issues where SDK internal logic ran before customer interceptors could modify the request (e.g., injected credentials were ignored). It also duplicated resolution logic across every service, making it harder to fix bugs consistently. Moving to pipeline stages fixes both problems.
Related
Fix: #6486 — Credentials injected via ExecutionInterceptor not respected
PR: #7017 — Move auth scheme/endpoint resolution from interceptor to pipeline stages
Summary
Starting in AWS SDK for Java v2.47.0, auth scheme resolution and endpoint resolution have moved from per-service generated interceptors to shared pipeline stages in
sdk-core. This fixes a bug where credentials injected via interceptors were ignored (#6486) and establishes clear separation between customer extension points (interceptors) and SDK internals.What Changed
RESOLVED_ENDPOINTin execution attributes is nownullduring interceptor execution (modifyRequest()/modifyHttpRequest()). Endpoint resolution happens after interceptors complete.SELECTED_AUTH_SCHEMEin execution attributes contains a placeholder during interceptor execution. Auth scheme resolution happens after interceptors complete.modifyHttpRequest()is the base service endpoint, not the fully resolved endpoint. For example, S3 requests will shows3.region.amazonaws.cominstead ofbucket.s3.region.amazonaws.comat that point.Who Is Affected
Most users are not affected. This change should be transparent for standard SDK usage.
You may be affected if your code:
SdkInternalExecutionAttribute.RESOLVED_ENDPOINTduringmodifyRequest()ormodifyHttpRequest(). It will now be null at that point.SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEMEduring interceptor execution. It will contain a placeholder.modifyHttpRequest()expecting the fully resolved endpoint (e.g.,bucket.s3.region.amazonaws.com). Endpoint resolution has not happened yet at that point, so the host will be the base service endpoint.Note: SdkInternalExecutionAttribute is an internal API. Backward compatibility is not guaranteed for internal attributes.
Bug Fix
Credentials injected via
ExecutionInterceptor.modifyRequest()(throughAwsRequestOverrideConfiguration.credentialsProvider()) are now correctly used for signing. Previously they were ignored because auth scheme resolution happened before interceptors ran.Migration Guide
Reading the resolved endpoint or auth scheme
Use
beforeTransmission(). Both endpoint resolution and auth scheme resolution are complete at that point:Overriding the endpoint
Modify the HTTP request URL directly in
modifyHttpRequest(). The pipeline detects the modification and preserves it:Custom signer
Register via
putAuthScheme()at client build time instead of manipulatingSELECTED_AUTH_SCHEMEin an interceptor:For full examples on implementing custom auth schemes, see the
AuthSchemejavadoc.Version Compatibility
If you run into
NoClassDefFoundError,NoSuchMethodError, orcannot find symbolerrors after upgrading, make sure all SDK dependencies are on the same version. We recommend using the BOM to manage SDK dependencies:Why We Made This Change
The SDK was using
ExecutionInterceptorfor internal auth/endpoint resolution, but this interface was designed for customer extensibility. This caused ordering issues where SDK internal logic ran before customer interceptors could modify the request (e.g., injected credentials were ignored). It also duplicated resolution logic across every service, making it harder to fix bugs consistently. Moving to pipeline stages fixes both problems.Related
Fix: #6486 — Credentials injected via ExecutionInterceptor not respected
PR: #7017 — Move auth scheme/endpoint resolution from interceptor to pipeline stages