Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I cure a call to the AWS Java SDK DynamoDB resulting in an ExpiredTokenException?

I have a long running AWS Java SDK DynamoDB application which behaves normally when I start it up. However, after some number of hours (around 12), I start receiving the same Exception over and over again with ANY call to the DynamoDB API. If I restart the server, the Exception disappears...only to reappear again later.

The exact ExpiredTokenException error text is:
The security token included in the request is expired (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ExpiredTokenException; Request ID: DEMTN0Q5BMPH5IQD9TUQMNO5SFVV4KQNSO5AEMVJF66Q9ASUAAJG)

like image 216
chaotic3quilibrium Avatar asked Aug 27 '15 17:08

chaotic3quilibrium


People also ask

What causes DynamoDB system errors?

The most likely cause of a failed read or a failed write is throttling. For BatchGetItem , one or more of the tables in the batch request does not have enough provisioned read capacity to support the operation. For BatchWriteItem , one or more of the tables does not have enough provisioned write capacity.

How do I resolve the error the security token included in the request is expired?

You must refresh the credentials before they expire. Another reason for expiration is using the incorrect time. A consistent and accurate time reference is crucial for many server tasks and processes. If your instance's date and time aren't set correctly, the AWS credentials are rejected.

Which class would you use to retrieve items from DynamoDB using Java?

To retrieve a single item, you can use the getItem method. Follow these steps: Create an instance of the DynamoDB class. Create an instance of the TableKeysAndAttributes class that describes a list of primary key values to retrieve from a table.


1 Answers

Summary:
Pass an instance of AWSCredentialsProvider (as opposed to AWSCredentials) to AmazonDynamoDBClient's constructor as this enables automatic refreshing of expired AWSCredentials (if the particular AWSCredentialsProvider has implemented the refresh functionality...which is the case with all the standard AWS provided ones).

Details:
To resolve the AWS Java SDK DynamoDB related ExpiredTokenException which starts with the prefix "The security token included in the request is expired (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ExpiredTokenException; Request ID: ...", you must alter your code to provide an instance of AWSCredentialsProvider (and stop using an instance of AWSCredentials - i.e. sans the "Provider" suffix) to the AmazonDynamoDBClient's constructor. By handing the AmazonDynamoDBClient's constructor an instance of AWSCredentialsProvider, you give it the ability to "automatically refresh the credentials" if/when the AWSCredentials expire (which I found in this AWS forum thread which requires an account to access).

To provide an explicit example in code, here's a generalization of what the code is producing the ExpiredTokenException:

AWSCredentialsProvider aWSCredentialsProvider =
  new SystemPropertiesCredentialsProvider();
    //the above line may be substituted for any valid
    //*Provider implementation
AWSCredentials aWSCredentials =
  aWSCredentialsProvider.getCredentials();
AmazonDynamoDBClient amazonDynamoDBClient =
  new AmazonDynamoDBClient(aWSCredentials);
...
amazonDynamoDBClient.listTables();
  //the above line is where the ExpiredTokenException is eventually thrown

And here is a generalization of the code eliminating the ExpiredTokenException:

AWSCredentialsProvider aWSCredentialsProvider =
  new SystemPropertiesCredentialsProvider();
    //substitute the above line for any valid *Provider implementation
AmazonDynamoDBClient amazonDynamoDBClient =
  new AmazonDynamoDBClient(aWSCredentialsProvider);
    //the above line is now passing an instance of AWSCredentialsProvider
    //as opposed to AWSCredentials
...
amazonDynamoDBClient.listTables();
  //the above line is now enabled, via the AWSCredentialsProvider, to 
  //automatically refresh the AWSCredentials if/when they have expired

Given how much I climbed all over the AWS Java SDK Javadocs and their provided examples (upon which I based most of my own code), I didn't once notice this specific nuance called out. Hence, the very detailed answer I'm providing for those who come after me (which likely will include myself, LOL).

like image 173
chaotic3quilibrium Avatar answered Sep 22 '22 10:09

chaotic3quilibrium