Spring Cloud AWS SQS fails to connect to service endpoint locally

38,652

Solution 1

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
        }
)

Solution 2

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

Solution 3

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.

  • System Property : com.amazonaws.sdk.disableEc2Metadata
  • Environment variable : 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)
    ...

Solution 4

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

Solution 5

Fix the problem adding in the application.yaml file:

logging:
  level:
    com:
      amazonaws:
        util:
          EC2MetadataUtils: error
Share:
38,652

Related videos on Youtube

Carven
Author by

Carven

Updated on July 09, 2022

Comments

  • Carven
    Carven almost 2 years

    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?

    • Saurav Kumar Singh
      Saurav Kumar Singh over 4 years
      Is your SQS has only IAM based access ?
    • Carven
      Carven over 4 years
      @SauravKumarSingh I don’t think so. I don’t remember creating the SQS queue to restrict only to IAM access unless that’s the default configuration.
    • smac2020
      smac2020 about 3 years
      Use the Official AWS Java API over this 3rd party API to invoke AWS Services from within a Spring app. For starters, you will get support from the AWS Java SDK team.
  • Carven
    Carven over 4 years
    I've just tried using 2.2.0.RELEASE but the same error is still occurring.
  • Carven
    Carven over 4 years
    I already have cloud.aws.region.auto set to false and cloud.aws.region.static set to my region but it seems like it's still attempting to retrieve from the EC2 meta data and resulting in the error.
  • nickolay.laptev
    nickolay.laptev over 4 years
    These are the only options that influence on using meta data service. If they don’t work, then you have Spring bug. However this is basic functionality and there are many people who use it. From your question I don’t see you set these properties, the way how you build sqsClient is not the same as setting these options via property file.
  • nickolay.laptev
    nickolay.laptev about 4 years
    It's in fact Spring bug. I experience the same problem now. Adding "cloud.aws.stack.auto=false" can be a workaround, however there are many warnings generated
  • Keith Bennett
    Keith Bennett almost 4 years
    Was a solution ever found for this? I am experiencing the same issue and have documented it here: stackoverflow.com/questions/63271529/….
  • Procrastinator
    Procrastinator over 3 years
    Please add some explanation to your code so that it'd be easy to understand for others
  • Arjun Gautam
    Arjun Gautam about 3 years
    github.com/arjun-sudo/AWS_Image_Upload Click here if you want to know in which project i got this error .
  • bigjel
    bigjel about 3 years
    Just added the parameters in IntelliJ run configuration and it works fine: logging.level.com.amazonaws.util.EC2MetadataUtils=error logging.level.com.amazonaws.internal.InstanceMetadataService‌​ResourceFetcher=erro‌​r