Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda PutObjectCommand failing with "Resolved credential object is not valid"

I have a lambda which is attempting to put an object in an S3 bucket.

The code to configure the s3 client is as follows:

const configuration: S3ClientConfig = {
  region: 'us-west-2',
};

if (process.env.DEVELOPMENT_MODE) {
  configuration.credentials = {
    accessKeyId: process.env.AWS_ACCESS_KEY!,
    secretAccessKey: process.env.AWS_SECRET_KEY!,
  }
}

export const s3 = new S3Client(configuration);

And the code to upload the file is as follows:

s3.send(new PutObjectCommand({
  Bucket: bucketName,
  Key: fileName,
  ContentType: contentType,
  Body: body,
}))

This works locally. The lambda's role includes a policy which in turn includes the following statement:

{
    "Action": [
        "s3:DeleteObject",
        "s3:PutObject"
    ],
    "Resource": [
        "arn:aws:s3:::BUCKET_NAME/*"
    ],
    "Effect": "Allow"
}

However, when I invoke this lambda, it fails with the following stack trace

Error: Resolved credential object is not valid
    at SignatureV4.validateResolvedCredentials (webpack://backend/../node_modules/@aws-sdk/signature-v4-multi-region/node_modules/@aws-sdk/signature-v4/dist-es/SignatureV4.js?:307:19)
    at SignatureV4.eval (webpack://backend/../node_modules/@aws-sdk/signature-v4-multi-region/node_modules/@aws-sdk/signature-v4/dist-es/SignatureV4.js?:50:30)
    at step (webpack://backend/../node_modules/tslib/tslib.es6.js?:130:23)
    at Object.eval [as next] (webpack://backend/../node_modules/tslib/tslib.es6.js?:111:53)
    at fulfilled (webpack://backend/../node_modules/tslib/tslib.es6.js?:101:58)

I'm using (what is currently) the latest javascript aws sdk, version 3.165.0. What am I missing here?

like image 495
cscan Avatar asked Jul 29 '26 09:07

cscan


2 Answers

The problem is that I was trying to load the configuration credentials from environment variables instead of relying on the IAM role. Turns out process.env.DEVELOPMENT_MODE was resolving to the string 'true' instead of the boolean true.

if (process.env.DEVELOPMENT_MODE === 'true') {
  configuration.credentials = {
    accessKeyId: process.env.AWS_ACCESS_KEY!,
    secretAccessKey: process.env.AWS_SECRET_KEY!,
  }
}
like image 167
cscan Avatar answered Jul 31 '26 03:07

cscan


This answer is regarding @cscan's question.

As a future visitor, I was able to figure out that this problem resulted from my script not assigning values to the credentials.

If you encounter this error, please make sure that the credentials are correctly assigned and if you are using an .env file, make sure that in your script, you have imported and configured dotenv, before using process.env to read from the .env file.

require 'dotenv'

//configure dotenv
dotenv.config()

//use process.env after configuring and importing dotenv
configuration.credentials = {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
}

You can try to assign these values manually to confirm if your issue if issue is from process.env

configuration.credentials = {
    accessKeyId: 'YOUR_ACCESS_KEY_ID',
    secretAccessKey: 'YOUR_SECRET_ACCESS_KEY',
}

You can always try and log the value of process.env to verify the root cause of your problem

console.log(process.env.AWS_ACCESS_KEY_ID) //undefined or Some real value

I hope this helps

like image 25
Simon Ugorji Avatar answered Jul 31 '26 03:07

Simon Ugorji