11

I'm using an AWS Lambda function (written in python) to send an email whenever an object is uploaded into a preset S3 bucket. The object is uploaded via the AWS PHP SDK into the S3 bucket and is using a multipart upload. Whenever I test out my code (within the Lambda code editor page) it seems to work fine and I only get a single email.

But when the object is uploaded via the PHP SDK, the Lambda function runs twice and sends two emails, both with different message ID's. I've tried different email addresses but each address receives exactly two, duplicate emails.

Can anyone guide me where could I be going wrong? I'm using the boto3 library that is imported with the sample python code to send the email.

2
  • First can you check you are not uploading twice. Is PutObject triggering lambda? What is the time difference between the duplicate emails? Commented Jan 14, 2016 at 18:54
  • @helloV The object is indeed uploaded once to the S3 bucket. The PutObject does trigger the lambda as the email is sent and received properly. The two emails are received exactly two seconds apart. Commented Jan 15, 2016 at 10:09

3 Answers 3

14

Yes, we have this as well and it's not linked to the email, it's linked to S3 firing multiple events for a single upload. Like a lot of messaging systems, Amazon does not guarantee "once only delivery" of event notifications from S3, so your Lambda function will need to handle this itself.

Not the greatest, but doable.

Some form of cache with details of the previous few requests so you can see if you've already processed the particular event message or not.

Sign up to request clarification or add additional context in comments.

4 Comments

How do you go about caching inside a Lambda function?
Perhaps using something like Redis or DynamoDB. The cache will need to survive between Lambda invocations, so it needs to be outside the Lambda function.
Could you give the documentation link about Amazon does not guarantee "once only delivery"
docs.aws.amazon.com/AmazonS3/latest/userguide/… "Amazon S3 event notifications are designed to be delivered at least once." The key part, "at least once". So, in the context of the question, the event notification from S3 to Lambda is guaranteed to be delivered at least once, but could be multiple times, as per the question. Most queueing and eventing systems default to "at least once" delivery. Some can handle co-ordinating "once, and once only", but this is typically not the default, and has a performance impact.
7

I am also facing the same issue, in my case on every PUT event in S3 bucket a lambda should trigger, it triggers twice with same aws_request_id and aws_lambda_arn.

To fix it, keep track of the aws_request_id (this id will be unique for each lambda event) somewhere and have a check on the handler. If the same aws_request_id exist then do nothing, otherwise process as usual.

2 Comments

how would you store the value of x-amz-request-id to prevent the multiple firing, the second trigger fires a new lambda which has no variable to compare to. Unless you are suggesting that request id must be stored in an RDS instance.
@Shek either persist the ID in a cache such as Redis, store it in DynamoDB with a sensible TTL, or build an idempotent process (for example a write to a DB, which is conditional upon the repeated identity not being present).
1

I ran into a similar issue, for me I was invoking the function using:

lambda_client = boto3.client('lambda') lambda_client.invoke(...) 

It turns out that because the function was long running it was silently throwing an error Read timeout on endpoint URL:. I discovered boto3 has some default retry functionality.

I was able to fix it by adding:

from botocore.client import Config cfg = Config(retries={'max_attempts': 0}, read_timeout=900) lambda_client = boto3.client('lambda', config=cfg) lambda_client.invoke(...) 

I know maybe not the cause of your issue but might help other people experiencing the same problem. Good luck!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.