Skip to content
Advertisement

Signature Error while updating S3 object metadata through boto3

I have a lambda function that takes S3 object from S3 events and updates it with the custom metadata.

Here is the boto3 script:

import json
import boto3

s3 = boto3.resource('s3')

def lambda_handler(event, context):
    key = event['Records'][0]['s3']['object']['key']
    key_name = key.split('/')
    bucket = event['Records'][0]['s3']['bucket']['name']
    print(key)
    print(bucket)
    s3_object = s3.Object(bucket, key)
    s3_object.metadata.update({'Cache-Control':'no-cache'})
    s3_object.copy_from(CopySource={'Bucket':bucket, 'Key':key}, Metadata=s3_object.metadata, MetadataDirective='REPLACE')

When I run the script, it gives me the following error:

An error occurred (SignatureDoesNotMatch) when calling the CopyObject operation: The request signature we calculated does not match the signature you provided. Check your key and signing method.: ClientError

(Note: I have given sufficient permission on lambda function role)

Do I need to create Signature here?

Advertisement

Answer

It is possible that the Key of the object has some strange characters in it.

Here is some slightly modified code that worked for me:

import boto3
import urllib

s3 = boto3.resource('s3')

def lambda_handler(event, context):

    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'])

    s3_object = s3.Object(bucket, key)
    s3_object.metadata.update({'Cache-Control':'no-cache'})
    s3_object.copy_from(CopySource={'Bucket':bucket, 'Key':key}, Metadata=s3_object.metadata, MetadataDirective='REPLACE')
Advertisement