Have you seen this error during deployment?
ServerlessError2: An error occurred: YourEventSourceMapping - Resource handler returned message: "Invalid request provided: Queue visibility timeout: 30 seconds is less than Function timeout: 300 seconds"
This might look confusing, but don’t worry — it’s easy to fix once you understand how Lambda and SQS work together.
What This Error Means
When AWS Lambda reads a message from SQS, that message becomes “invisible” to other consumers for a short time. This is called the visibility timeout.
If your Lambda function takes longer to process than the visibility timeout, the message becomes visible again — and Lambda may reprocess it, which can lead to:
- Duplicate processing
- Data inconsistency
- Unwanted side effects (like charging twice or sending repeated emails)
In Simple Terms
- Your Lambda is allowed to run for up to 300 seconds (5 minutes)
- But your SQS visibility timeout is only 30 seconds
- So SQS thinks the function failed and retries the same message while it’s still running
How to Fix It
You need to increase the visibility timeout of your SQS queue so that it matches (or slightly exceeds) the Lambda function’s timeout.
Best Practice: Standard Queue + DLQ Setup
If you’re using two SQS queues — a main standard queue and a dead letter queue (DLQ) — here’s the best practice configuration:
Main SQS queue:
- Visibility timeout should be equal or greater than Lambda timeout
- Set it to 310 seconds (Lambda timeout is 300)
DLQ queue:
- Visibility timeout can be shorter, like 60 seconds
- This queue is only used for failed messages and usually processed manually or by another system
Example Serverless Framework Configuration
Here’s how you can configure this in your serverless.yml
:
functions: myLambdaFunction: handler: src/handler.lambda_handler timeout: 300 resources: Resources: MainQueue: Type: AWS::SQS::Queue Properties: QueueName: ${sls:stage}-main-queue VisibilityTimeout: 310 RedrivePolicy: deadLetterTargetArn: !GetAtt DLQ.Arn maxReceiveCount: 3 DLQ: Type: AWS::SQS::Queue Properties: QueueName: ${sls:stage}-dead-letter-queue VisibilityTimeout: 60 MessageRetentionPeriod: 1209600 # 14 days
Summary of Recommended Settings
Queue Type | Visibility Timeout |
---|---|
Main SQS queue | 310 seconds (≥ Lambda) |
DLQ queue | 60 seconds (short is fine) |
What If You Want to Retry Messages from DLQ?
Lambda will not automatically retry messages from the DLQ. If you want to reprocess them, you can:
- Manually move the message back to the main queue
- Use a second Lambda function to poll the DLQ and retry the logic
Final Tips
- Always set visibility timeout to match or exceed your Lambda timeout
- Add a small buffer (5–10 seconds) to be safe
- Use a DLQ to capture failures and keep your system reliable
- Monitor DLQ activity using CloudWatch to spot any unusual spikes or issues
With just a few lines of configuration, you can prevent duplicate message handling and make your serverless setup much more reliable. Let me know if you need help creating a retry Lambda for DLQ messages!
Additional Resources:
- AWS Docs – SQS Visibility Timeout Overview
- AWS Docs – Using Lambda with Amazon SQS
- AWS Docs – Configuring Visibility Timeout