Reputation: 15638
I'm trying to use Spring Cloud's AWS SQS in a project I'm working on. At this time, I'm only running the application locally on my dev machine. Thus, what I want is to connect to the SQS on AWS without having to deploy my app to an EC2 instance.
However, it seems like the AWS SDK used in Spring Cloud's AWS package will attempt to authenticate through metadata and wants to resolve 169.254.169.254/latest/meta-data/instance-id
. Since I'm still the running the app locally, the endpoint cannot be resolved and an error is thrown:
2019-12-29 16:38:27.420 WARN 22462 --- [ restartedMain] com.amazonaws.util.EC2MetadataUtils : Unable to retrieve the requested metadata (/latest/meta-data/instance-id). Failed to connect to service endpoint:
com.amazonaws.SdkClientException: Failed to connect to service endpoint:
at com.amazonaws.internal.EC2ResourceFetcher.doReadResource(EC2ResourceFetcher.java:100) ~[aws-java-sdk-core-1.11.699.jar:na]
at com.amazonaws.internal.EC2ResourceFetcher.doReadResource(EC2ResourceFetcher.java:70) ~[aws-java-sdk-core-1.11.699.jar:na]
at com.amazonaws.internal.InstanceMetadataServiceResourceFetcher.readResource(InstanceMetadataServiceResourceFetcher.java:75) ~[aws-java-sdk-core-1.11.699.jar:na]
at com.amazonaws.internal.EC2ResourceFetcher.readResource(EC2ResourceFetcher.java:62) ~[aws-java-sdk-core-1.11.699.jar:na]
at com.amazonaws.util.EC2MetadataUtils.getItems(EC2MetadataUtils.java:400) ~[aws-java-sdk-core-1.11.699.jar:na]
at com.amazonaws.util.EC2MetadataUtils.getData(EC2MetadataUtils.java:369) ~[aws-java-sdk-core-1.11.699.jar:na]
at org.springframework.cloud.aws.context.support.env.AwsCloudEnvironmentCheckUtils.isRunningOnCloudEnvironment(AwsCloudEnvironmentCheckUtils.java:38) ~[spring-cloud-aws-context-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.cloud.aws.context.annotation.OnAwsCloudEnvironmentCondition.matches(OnAwsCloudEnvironmentCondition.java:37) ~[spring-cloud-aws-context-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:221) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:587) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
...
I've tried to explicitly supply an SQS endpoint in my bean, but it still attempts to connect to 169.254.169.254
resulting in the error above:
public AmazonSQSAsync sqsClient() {
EndpointConfiguration endpointConfig = new AwsClientBuilder.EndpointConfiguration(
"sqs.us-east-1.amazonaws.com",
"us-east-1"
);
return AmazonSQSAsyncClientBuilder
.standard()
.withEndpointConfiguration(endpointConfig)
.withCredentials(new AWSStaticCredentialsProvider(new DefaultAWSCredentialsProviderChain().getCredentials()))
.build();
}
Although I'm not certain about this, I suspect that the error is occurring because I'm running the app locally on my dev machine and so it couldn't resolve to the endpoint. But I'm not entirely sure about this too because I'm running other AWS services in the same app using the AWS SDK and I don't have this error.
I've the following dependencies in my pom.xml and it appears that having any one of them will cause the error to occur. That's, I don't even have to create the beans to have that error. Adding these dependencies will immediately, for some reason, causes the SDK to attempt to resolve that endpoint and fail with that error.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-aws</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-aws-messaging</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
What else should I do to fix the error that it failed to connect to service endpoint?
Upvotes: 42
Views: 84265
Reputation: 197
This was coming from an internal dependency at my company, so I couldn't get any of the previously posted solutions to work. What worked for me was to simply set in my environment variables AWS_REGION = 'us-east-1'.
Upvotes: 0
Reputation: 959
I have received below errors when running Spring Boot Project for AWS SNS
i.InstanceMetadataServiceResourceFetcher : Fail to retrieve token
com.amazonaws.util.EC2MetadataUtils : Unable to retrieve the requested metadata (/latest/dynamic/instance-identity/document). Failed to connect to service endpoint:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'stackResourceRegistryFactoryBean' defined in class path resource [org/springframework/cloud/aws/autoconfigure/context/ContextStackAutoConfiguration.class]: Unsatisfied dependency expressed through method 'stackResourceRegistryFactoryBean' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'amazonCloudFormation' defined in class path resource [org/springframework/cloud/aws/autoconfigure/context/ContextStackAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: There is no EC2 meta data available, because the application is not running in the EC2 environment. Region detection is only possible if the application is running on a EC2 instance
Error creating bean with name 'org.springframework.cloud.aws.core.env.ResourceIdResolver.BEAN_NAME': Invocation of init method failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'stackResourceRegistryFactoryBean' defined in class path resource [org/springframework/cloud/aws/autoconfigure/context/ContextStackAutoConfiguration.class]: Unsatisfied dependency expressed through method 'stackResourceRegistryFactoryBean' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'amazonCloudFormation' defined in class path resource [org/springframework/cloud/aws/autoconfigure/context/ContextStackAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: There is no EC2 meta data available, because the application is not running in the EC2 environment. Region detection is only possible if the application is running on a EC2 instance
Resolution applied: Add below code snippet to SpringBootApplication & Click on Run Button in the IDE
@SpringBootApplication(
exclude = {
org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration.class
}
)
Upvotes: 27
Reputation: 624
The following configuration worked for me:
cloud:
aws:
region:
auto: false
static: eu-west-1
use-default-aws-region-chain: true
stack: false
stack.auto: false
logging:
level:
com:
amazonaws:
internal:
InstanceMetadataServiceResourceFetcher: error
util:
EC2MetadataUtils: error
Upvotes: 17
Reputation: 303
I also faced similar error but not from the Spring cloud. When i added below configuration in application.properties, error went away.
logging.level.com.amazonaws.util.EC2MetadataUtils=error logging.level.com.amazonaws.internal.InstanceMetadataServiceResourceFetcher=error
But i'm facing some other issues while opening s3a path. Then i printed the stacktrace of the exception and then i got below error
Caused by: com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain: [BasicAWSCredentialsProvider: Access key or secret key is null, WebIdentityTokenCredentialsProvider: You must specify a value for roleArn and roleSessionName, EnvironmentVariableCredentialsProvider: Unable to load AWS credentials from environment variables (AWS_ACCESS_KEY_ID (or AWS_ACCESS_KEY) and AWS_SECRET_KEY (or AWS_SECRET_ACCESS_KEY)), com.amazonaws.auth.InstanceProfileCredentialsProvider@7700439a: Failed to connect to service endpoint: ]
Already credentials are there /.aws folder but not sure why application still giving the error. Fixed by creating environment variables AWS_ACCESS_KEY_ID, AWS_SECRET_KEY and AWS_SESSION_TOKEN
Upvotes: 1
Reputation: 965
I know many people have already explained what's issue and how to skip this error. But, all the above method didn't work for me. Finally after lot of search I set following aws configuration property and it worked for me.
cloud.aws.region.use-default-aws-region-chain=true
cloud.aws.stack.auto=false
cloud.aws.credentials.access-key=
cloud.aws.credentials.secret-key=
cloud.aws.region.auto=false
cloud.aws.region.static=
cloud.aws.stack=false
logging.level.com.amazonaws.util.EC2MetadataUtils=error
logging.level.com.amazonaws.internal.InstanceMetadataServiceResourceFetcher=error
Upvotes: 20
Reputation: 329
I was getting same kind of error when running s3 bucket in spring boot i solved using different location used while creating bucket:
return AmazonS3ClientBuilder
.standard()
.withRegion("us-east-1") //This is the code i added to fix
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.build();
Upvotes: 3
Reputation: 81
Fix the problem adding in the application.yaml file:
logging:
level:
com:
amazonaws:
util:
EC2MetadataUtils: error
Upvotes: 7
Reputation: 59
The issue is with the spring-cloud version Hoxton.SR8. Replace your spring-cloud version in your pom.xml with Finchley.SR1.
Upvotes: 3
Reputation: 361
When using the AWS Java SDK outside of an EC2 instance, you can disable loading credentials or regions from EC2 Metadata instance service with a System property or an Environment variable.
com.amazonaws.sdk.disableEc2Metadata
AWS_EC2_METADATA_DISABLED
However, you will still get a warning at application startup, it tells you the EC2Metadata is disabled by configuration : "EC2 Instance Metadata Service is disabled"
2020-03-27 18:10:42.483 WARN 71123 --- [main] com.amazonaws.util.EC2MetadataUtils : Unable to retrieve the requested metadata (/latest/meta-data/instance-id). EC2 Instance Metadata Service is disabled
com.amazonaws.AmazonClientException: EC2 Instance Metadata Service is disabled
at com.amazonaws.internal.InstanceMetadataServiceResourceFetcher.readResource(InstanceMetadataServiceResourceFetcher.java:65)
at com.amazonaws.internal.EC2ResourceFetcher.readResource(EC2ResourceFetcher.java:66)
at com.amazonaws.util.EC2MetadataUtils.getItems(EC2MetadataUtils.java:402)
at com.amazonaws.util.EC2MetadataUtils.getData(EC2MetadataUtils.java:371)
at org.springframework.cloud.aws.context.support.env.AwsCloudEnvironmentCheckUtils.isRunningOnCloudEnvironment(AwsCloudEnvironmentCheckUtils.java:38)
...
Upvotes: 9
Reputation: 2565
cloud.aws.region.auto
property to false
in Spring application properties (or via environment variables etc.).cloud.aws.region.static
property.This will tell Spring not to use automatic detection based EC2 meta data. Some details.
You may need to configure credentials similarly, you can find related info in the same doc.
Upvotes: 2
Reputation: 1458
As far as I understand its trying to check if your application is running on cloud environment, from the 5th last line of the stacktrace
org.springframework.cloud.aws.context.support.env.AwsCloudEnvironmentCheckUtils.isRunningOnCloudEnvironment(AwsCloudEnvironmentCheckUtils.java:38)
I checked out the the repo
and here is the code snippet -
public static boolean isRunningOnCloudEnvironment() {
if (isCloudEnvironment == null) {
try {
isCloudEnvironment = EC2MetadataUtils
.getData(EC2_METADATA_ROOT + "/instance-id", 1) != null;
}
catch (AmazonClientException e) {
isCloudEnvironment = false;
}
}
return isCloudEnvironment;
}
As per the snippet it tried to fetch instance metadata
and if it fails it return false
, which means you are not on the Cloud Environment
. However this code is expected to Catch AmazonClientException
but the stacktrace you shared is throwing SdkClientException
exception, which this part of the snippet can't catch
and hence can't return false
that you are not on a cloud environment.
Seems like some issue with this build of the library, As per the stacktrace you are using 2.2.1.RELEASE1
which was released 9 days back only. Could you please try to use one of the older version and then report if you are still facing the same issue.
Or as a temporary fix you can try tunnelling to your VPC's entry server
. You can use sshuttle for tunnelling purpose if you want. This will mostly make that IP reachable from local machine as well.
Upvotes: 3