I have an issue with the S3 Client from aws sdk v3 :
If i use the S3Client, as specified in the documentation, with the credentials provided using the environent variables, i get the error The AWS Access Key Id you provided does not exist in our records.
At first i thought it was because i didn't use the correct AWS_ACCESS_KEY_ID, but adding this line just after the client initialization fixed the issue, and logged the correct values :
s3.config.credentials().then(console.log)
What bother me the most is the fact that if i call this line anywhere else (ie: in a async function), it does not fix the issue.
await) ?Here is my code :
const s3Config: S3ClientConfig = {}
s3Config.endpoint = new HttpRequest({...} as Endpoint) // used with a local s3 server
const s3 = new S3Client(s3Config);
// this is the hack
s3.config.credentials().then(console.log)
export const upload = async (...) => {
// here it does not work
// await s3.config.credentials().then(console.log)
const streamUpload = new Upload({client: s3,...})
return await streamUpload.done()
}
export const getTempLink = async (...) => {
// here it does not work
// await s3.config.credentials().then(console.log)
//* Get the pre-signed url
const command = new GetObjectCommand({Bucket,Key})
return await getSignedUrl(s3 as any, command as any, { expiresIn })
}
Thanks for your help !
I got a similar issue with that
First was the difference between the aws-sdk vs aws-sdk/client-s3
My problem was that in the .env file the key names are like this
ACCESS_KEY_ID,
SECRET_ACCESS_KEY,
AWS_SESSION_TOKEN
That don't work, so I change the name like following and ready to go. It took the credentials.
AWS_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY,
AWS_SESSION_TOKEN,
Remember that AWS has a chain of precedence for credentials
Here are the few things I found to answer my questions :
As mentioned in the question the line who makes it work is
await s3.config.credentials()
As answered here using service constructors you can have multiple AWS configs. Also, as Programmer89 precised, the chain of precedence matter, but there is a catch :
The AWS clients don't load the config right away, but only when it's necessary.
Using the config.credentials() function ensures that the config is loaded immediately.
This config needs to be loaded right away because the same AWS SDK is used with other configs (using custom DynamoDB and S3 endpoints for local tests).
If called anytime after, it seems to use the last environment variable used with that SDK and not the one available at the time of calling the constructor.
I'm not sure, it may or may not but we only had that issue for local tests.
In production, those processes are better separated. Locally the client does not stay instantiated for more than one call so I did not look any further.
It doesn't seem to matter as long as the client started to load the config (ie: the Promise started).
I hope the answers I found here could help someone else having the same issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With