Description

Ensure that every AWS Lambda function has a dead-letter queue (DLQ) configured. The DLQ is an Amazon SQS queue or Amazon SNS topic that receives the events of asynchronous invocations that still fail after all retries, so they can be reviewed and processed again.

Rationale

Without a DLQ, events from failed asynchronous invocations are discarded once retries are exhausted. Processing failures stay hidden and the events cannot be replayed or audited, which affects availability and data integrity. In security-related pipelines, such as log processing or alerting functions, this can mean that security events are silently lost. Configuring a DLQ, preferably an SQS queue, granting the function permission to send to it and alarming on its queue depth makes failures visible and recoverable.

Impact

  • Keeps the events of failed asynchronous invocations so they can be investigated and reprocessed

  • Makes processing failures visible, especially when combined with a CloudWatch alarm on the queue

  • Small additional cost for the SQS queue or SNS topic

  • Has no effect on synchronous invocations or event source mappings (for example SQS, Kinesis or DynamoDB triggers)

Default Value

No dead-letter queue is configured for a new Lambda function.

Pre-Requisites

  • IAM permissions: lambda:ListFunctions, lambda:GetFunctionConfiguration and lambda:UpdateFunctionConfiguration

  • An SQS queue or SNS topic in the same region to use as the DLQ

  • The function's execution role must allow sqs:SendMessage on the queue or sns:Publish on the topic (and use of the KMS key if the queue or topic is encrypted with a customer managed key)

Remediation

Test Plan

Console:

  1. Sign in to the AWS Management Console at https://console.aws.amazon.com.

  2. Open the AWS Lambda console and select a function.

  3. Select the Configuration tab and then Asynchronous invocation.

  4. Check whether a Dead-letter queue is set.

  5. Repeat for each function in each region in use.

  6. If no dead-letter queue is set, follow the implementation steps.

CLI:

List each function with its dead-letter queue:

aws lambda list-functions --region <REGION> --query "Functions[].[FunctionName,DeadLetterConfig.TargetArn]" --output table

A function fails if it has no dead-letter queue (TargetArn is None). Failure destinations configured for asynchronous invocation are not counted as a dead-letter queue.

Implementation Steps

Console:

  1. Sign in to the AWS Management Console at https://console.aws.amazon.com.

  2. Open the AWS Lambda console and select the function.

  3. Select the Configuration tab and then Asynchronous invocation.

  4. Choose Edit.

  5. Under Dead-letter queue service, select Amazon SQS or Amazon SNS and choose the queue or topic.

  6. Choose Save.

  7. Repeat for each affected function in each region in use.

CLI:

Set the dead-letter queue of the function:

aws lambda update-function-configuration --region <REGION> --function-name <FUNCTION_NAME> --dead-letter-config TargetArn=<DLQ_ARN>

Backout Plan

  1. Sign in to the AWS Management Console at https://console.aws.amazon.com.

  2. Open the AWS Lambda console and select the function.

  3. Select the Configuration tab, then Asynchronous invocation, and choose Edit.

  4. Set Dead-letter queue service to None and choose Save.

CLI:

Remove the dead-letter queue by setting an empty target ARN:

aws lambda update-function-configuration --region <REGION> --function-name <FUNCTION_NAME> --dead-letter-config "{\"TargetArn\":\"\"}"

Note: rolling back means events from failed asynchronous invocations are discarded again once retries are exhausted.

Reference