diff --git a/hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/auth/MarshalledCredentialBinding.java b/hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/auth/MarshalledCredentialBinding.java index 120d0f0a5a8..f1b8b48dd7f 100644 --- a/hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/auth/MarshalledCredentialBinding.java +++ b/hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/auth/MarshalledCredentialBinding.java @@ -25,6 +25,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import com.amazonaws.ClientConfiguration; +import com.amazonaws.SdkClientException; import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.AWSCredentialsProvider; import com.amazonaws.auth.AWSSessionCredentials; @@ -33,6 +34,8 @@ import com.amazonaws.auth.BasicSessionCredentials; import com.amazonaws.services.securitytoken.AWSSecurityTokenService; import com.amazonaws.services.securitytoken.model.Credentials; import com.google.common.annotations.VisibleForTesting; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.s3a.Invoker; @@ -53,6 +56,9 @@ import static org.apache.hadoop.fs.s3a.S3AUtils.lookupPassword; */ public final class MarshalledCredentialBinding { + private static final Logger LOG = + LoggerFactory.getLogger(MarshalledCredentialBinding.class); + private MarshalledCredentialBinding() { } @@ -194,15 +200,23 @@ public final class MarshalledCredentialBinding { final String stsRegion, final int duration, final Invoker invoker) throws IOException { - final AWSSecurityTokenService tokenService = - STSClientFactory.builder(parentCredentials, - awsConf, - stsEndpoint.isEmpty() ? null : stsEndpoint, - stsRegion) - .build(); - return fromSTSCredentials( - STSClientFactory.createClientConnection(tokenService, invoker) - .requestSessionCredentials(duration, TimeUnit.SECONDS)); + try { + final AWSSecurityTokenService tokenService = + STSClientFactory.builder(parentCredentials, + awsConf, + stsEndpoint.isEmpty() ? null : stsEndpoint, + stsRegion) + .build(); + return fromSTSCredentials( + STSClientFactory.createClientConnection(tokenService, invoker) + .requestSessionCredentials(duration, TimeUnit.SECONDS)); + } catch (SdkClientException e) { + if (stsRegion.isEmpty()) { + LOG.error("Region must be provided when requesting session credentials.", + e); + } + throw e; + } } } diff --git a/hadoop-tools/hadoop-aws/src/site/markdown/tools/hadoop-aws/troubleshooting_s3a.md b/hadoop-tools/hadoop-aws/src/site/markdown/tools/hadoop-aws/troubleshooting_s3a.md index a6eb3494938..5b7421c31d5 100644 --- a/hadoop-tools/hadoop-aws/src/site/markdown/tools/hadoop-aws/troubleshooting_s3a.md +++ b/hadoop-tools/hadoop-aws/src/site/markdown/tools/hadoop-aws/troubleshooting_s3a.md @@ -419,6 +419,28 @@ When trying to write or read SEE-KMS-encrypted data, the client gets a The caller does not have the permissions to access the key with which the data was encrypted. +### "Unable to find a region via the region provider chain." when using session credentials. + +Region must be provided when requesting session credentials, or an exception will be thrown with the message: +``` +com.amazonaws.SdkClientException: Unable to find a region via the region provider +chain. Must provide an explicit region in the builder or setup environment to supply a region. +``` +In this case you have to set the `fs.s3a.assumed.role.sts.endpoint` property to a valid +S3 sts endpoint and region like the following: + +```xml + + fs.s3a.assumed.role.sts.endpoint + ${sts.endpoint} + + + fs.s3a.assumed.role.sts.endpoint.region + ${sts.region} + +``` + + ## Connectivity Problems ### Error message "The bucket you are attempting to access must be addressed using the specified endpoint"