java - SQS ExpiredToken: The security token included in the request is expired status code: 403 -


i have long-running worker process running on ec2 consumes items sqs queue. after time (8-12 hours, reckon) begin getting expired security token errors. expect aws lib handle refresh of credentials automatically seems not case. in anyway handled within client? happens when use defaultcredentialsproviderchain generate access. error not occur when used key , secret. stacktrace below:

com.amazonaws.amazonserviceexception: security token included in request expired (service: amazonsqs; status code: 403; error code: expiredtoken; request id: 6ff6e1a0-d668-5ac5-bcd7-ae30058f25c0)     @ com.amazonaws.http.amazonhttpclient.handleerrorresponse(amazonhttpclient.java:1182)     @ com.amazonaws.http.amazonhttpclient.executeonerequest(amazonhttpclient.java:770)     @ com.amazonaws.http.amazonhttpclient.executehelper(amazonhttpclient.java:489)     @ com.amazonaws.http.amazonhttpclient.execute(amazonhttpclient.java:310)     @ com.amazonaws.services.sqs.amazonsqsclient.invoke(amazonsqsclient.java:2419)     @ com.amazonaws.services.sqs.amazonsqsclient.receivemessage(amazonsqsclient.java:1130)     @ com.amazonaws.services.sqs.amazonsqsasyncclient$24.call(amazonsqsasyncclient.java:1783)     @ com.amazonaws.services.sqs.amazonsqsasyncclient$24.call(amazonsqsasyncclient.java:1779)     @ java.util.concurrent.futuretask.run(futuretask.java:266)     @ java.util.concurrent.threadpoolexecutor.runworker(threadpoolexecutor.java:1142)     @ java.util.concurrent.threadpoolexecutor$worker.run(threadpoolexecutor.java:617)     @ java.lang.thread.run(thread.java:745) 

the workaround found renew awscredentials everytime encountered expired token error , reset sqs client.

awscredentials = (new defaultawscredentialsproviderchain).getcredentials sqs = simplesqsclient(awscredentials, regions.us_east_1) queuesqs = sqs.simple(queuename(queuename), true) 

note: using wrapper kifi/franz

the aws sdks indeed capable of cycling temporary credentials inherited instance profile, passing explicit awscredentials object in constructor of simplesqsclient believe denying opportunity so.

you didn't explicitly state application inheriting instance role, there enough evidence in post infer case:

  • your application running on ec2.
  • defaultawscredentialsproviderchain's behavior "instance profile credentials delivered through amazon ec2 metadata service" if can find no other credentials.
  • you're seeing behavior when not explicitly passing own known access/secret keys.

the specific behavior automatic credentials refresh described in documentation:

the automatic credentials refresh happens when use default client constructor, creates own instanceprofilecredentialsprovider part of default provider chain, or when pass instanceprofilecredentialsprovider instance directly client constructor. if use method obtain or pass instance profile credentials, responsible checking , refreshing expired credentials.

by passing awscredentials directly instead of awscredentialsprovider, become responsible checking , refreshing expired credentials. on plus side, workaround fine if want keep passing credentials explicitly.

simplesqsclient has constructor work better use case:

new simplesqsclient(     credentialprovider: com.amazonaws.auth.awscredentialsprovider,     region: com.amazonaws.regions.regions,     buffered: boolean ) 

example:

simplesqsclient sqs = simplesqsclient(new defaultawscredentialsproviderchain(), regions.us_east_1, false) 

example, explicitly using instanceprofilecredentialsprovider:

simplesqsclient sqs = simplesqsclient(new instanceprofilecredentialsprovider(), regions.us_east_1, false) 

further reading:


Comments

Popular posts from this blog

java - nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet Hibernate+SpringMVC -

sql - Postgresql tables exists, but getting "relation does not exist" when querying -

asp.net mvc - breakpoint on javascript in CSHTML? -