🧩 How to Fix SQS Visibility Timeout in AWS Lambda

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 TypeVisibility Timeout
Main SQS queue310 seconds (≥ Lambda)
DLQ queue60 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:

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.