Skip to content

Instantly share code, notes, and snippets.

@cevatkerim
Forked from cmawhorter/troubleshooting.md
Created October 7, 2016 13:52
Show Gist options
  • Save cevatkerim/68e8e2395b8be0dd7f89b7b19c0e42dd to your computer and use it in GitHub Desktop.
Save cevatkerim/68e8e2395b8be0dd7f89b7b19c0e42dd to your computer and use it in GitHub Desktop.
Solution to AWS Lambda node.js UnrecognizedClientException "The security token included in the request is invalid."

Troubleshooting AWS unauthorized errors in lambda requests

This is mainly for node.js but might apply to other environments. Unsure.

If you are running a AWS Lambda function that calls another AWS service and getting an error about invalid tokens or other access denied errors, do this:

Check IAM

The role assigned to your lambda function will need permission to perform the actions. Check IAM and make sure the role has all the permissions.

I usually give Full Access to the service in question (e.g. DynamoDB) if I suspect a problem here. I then work backward toward the granular rules. (Sometimes services require more permissions than you expect.)

Verify your settings and incoming data

Example below. Check the logs for results.

module.exports.handler = function(event, context) {
  // incoming data ok?
  console.log('event', JSON.stringify(event, null, 2));
  // env vars ok? (mostly set by AWS lambda, but might have some of yours)
  console.log('env', JSON.stringify(process.env, null, 2));
  // anything weird with the AWS service instance?
  console.log('dynamodb client', JSON.stringify(db._dynamodbClient));
  // what about the service config?
  console.log('dynamodb service', JSON.stringify(db._dynamodbClient.service, null, 2));
  // ...

Beware env credentials

This has bit me a couple times now and the solution isn't immediately obvious. Lambda automatically generates temporary aws credentials for the lambda function to use. These temporary credentials get added to process.env by Lambda

For some reason though, if you try to set these manually when creating a dynamodb client for example, it won't work.

It seems like best practice here is to always store credentials in environment and let the AWS sdk detect them.

Example:

This will work on local but fail on lambda:

var dynamodb = new AWS.DynamoDB.DocumentClient({
  accessKeyId: process.env.AWS_ACCESS_KEY_ID,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  region: process.env.AWS_DEFAULT_REGION,
});

This works on lambda AND local (as long as your env vars are named properly):

var dynamodb = new AWS.DynamoDB.DocumentClient({ region: process.env.AWS_DEFAULT_REGION });

I'm not exactly sure why this works, but even moving that creation inside the handler scope doesn't fix it, so it doesn't seem to be a race with client creation and process.env being ready.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment