I am using node.js to upload image to my s3 bucket on my local environment using localstack
here is my API code:
const s3 = new AWS.S3({
accessKeyId: 'testKEYId',
secretAccessKey: 'testSecret',
region: 'ap-south-1',
sslEnabled: false,
endpoint: 'http://localhost:4566',
});
app.post('/upload-1', upload.any(), (req, res) => {
const imagePath = './myfolder/my-image.jpg'; // Update with your image file path
const bucketName = 'my-buckert'; // Update with your S3 bucket name
const remoteFileName = 'uploaded_image.jpg';
const fileContent = fs.readFileSync(imagePath);
console.log(fileContent);
const params = {
Bucket: bucketName,
Key: remoteFileName,
Body: fileContent,
};
const bucketParams = {
Bucket: bucketName,
}
s3.upload(params, (err, data) => {
if (err) {
console.error('Error uploading image to S3:', err);
} else {
console.log('Image uploaded successfully. S3 location:', data.Location);
}
});
});
when i am calling this API then i am getting this error:
exception during call chain: Unable to parse request (not well-formed (invalid token): line 1, column 0), invalid XML received:
This issue stems from using
Virtual-Hosted
style requests against LocalStack when usinglocalhost
as the endpoint.Your SDK is prepending the bucket to your host which leads to a request looking like this:
http://my-buckert.localhost:4566/uploaded_image.jpg
LocalStack is not able to parse the bucket name from your host if the bucket name is is not followed by
.s3.
, and will treat this request as aCreateBucket
call.There are two solutions to this, outlined in the documentation here: https://docs.localstack.cloud/user-guide/aws/s3/#path-style-and-virtual-hosted-style-requests
In your case, the simplest would be to use
s3ForcePathStyle
for your client. Creating your client this way should fix your issue:More about the configuration of the javascript AWS SDK here: https://docs.localstack.cloud/user-guide/integrations/sdks/javascript/