SQS queues should have a dead-letter queue configured
When a consumer fails to process a message, SQS returns it to the queue for redelivery. Without a DLQ, poison messages cycle indefinitely, consuming compute, inflating costs, and blocking legitimate traffic. A DLQ captures these failures so you can inspect the message payload, replay it after fixing the bug, or alert on accumulation.
Silent message loss is worse than a noisy failure. Configuring a DLQ with an appropriate maxReceiveCount (typically between 3 and 5) gives your application a bounded retry window before isolating the problem message. That directly cuts mean-time-to-resolution for production incidents involving message processing failures.
Retrofit consideration
Each existing queue needs a corresponding DLQ created and a redrive policy attached. FIFO queues require a FIFO DLQ. At scale, that means auditing every queue and provisioning matching DLQs with correct naming and encryption settings before you can apply the policy without errors.
Implementation
Choose the approach that matches how you manage Terraform.
If you use terraform-aws-modules/sqs/aws, set the right module inputs for this control. You can later migrate to the compliance.tf module with minimal changes because it is compatible by design.
module "sqs" {
source = "terraform-aws-modules/sqs/aws"
version = ">=5.0.0"
fifo_queue = false
name = "abc123"
}
Use AWS provider resources directly. See docs for the resources involved: aws_sqs_queue.
resource "aws_sqs_queue" "this" {
name = "pofix-abc123"
redrive_policy = jsonencode({ deadLetterTargetArn = "arn:aws:sqs:us-east-1:123456789012:example-queue", maxReceiveCount = 5 })
}
What this control checks
The policy checks each aws_sqs_queue resource for a redrive policy directing failed messages to a DLQ. Two configuration paths are accepted: the aws_sqs_queue_redrive_policy resource, which takes queue_url and a policy JSON string containing deadLetterTargetArn and maxReceiveCount, or the redrive_policy argument set directly on aws_sqs_queue. To pass, deadLetterTargetArn must reference an existing SQS queue ARN and maxReceiveCount must be an integer from 1 to 1000. It fails when neither a redrive_policy argument nor a corresponding aws_sqs_queue_redrive_policy resource exists for the queue. The DLQ must be a separate aws_sqs_queue resource; FIFO queues require a FIFO DLQ with a name ending in .fifo.
Common pitfalls
FIFO queue requires a FIFO DLQ
If your source queue has
fifo_queue = true, the dead-letter target must also be a FIFO queue. Pointing a FIFO queue's redrive policy at a standard DLQ causes an API error at apply time. The DLQaws_sqs_queueresource must also setfifo_queue = truewith a name ending in.fifo.maxReceiveCount set too high or too low
Setting
maxReceiveCountto 1 routes messages to the DLQ after a single failure, which is too aggressive for transient errors like a brief downstream timeout. Setting it near 1000 effectively defeats the DLQ. Most workloads are well-served by a value between 3 and 5.DLQ retention period shorter than source queue
Messages expire from the DLQ before anyone can investigate them if
message_retention_secondsis shorter than the source queue's retention period. Set DLQ retention to at least 14 days (1209600 seconds) to give engineers a realistic window to respond.Inline redrive_policy JSON conflicts with separate resource
Using both the
redrive_policyargument onaws_sqs_queueand a separateaws_sqs_queue_redrive_policyresource for the same queue causes perpetual drift. Pick one approach and use it consistently across your codebase.DLQ itself has no monitoring
Configuring a DLQ satisfies this control, but without a CloudWatch alarm on
ApproximateNumberOfMessagesVisiblefor the DLQ, failed messages accumulate unnoticed. The DLQ only helps if someone watches it.
Audit evidence
The primary evidence artifact is AWS Config managed rule sqs-dead-letter-queue-enabled evaluation results showing all queues as COMPLIANT. CLI output from aws sqs get-queue-attributes --attribute-names RedrivePolicy for each queue should return a JSON object with deadLetterTargetArn and maxReceiveCount populated. CloudWatch metrics on the DLQ (ApproximateNumberOfMessagesVisible) confirm the DLQ is active.
CSPM scan reports should list each queue with its redrive policy status. Where CloudWatch alarms are configured on DLQ depth, the alarm configuration works as evidence of operational follow-through beyond the baseline configuration check.
Related controls
Tool mappings
Use these identifiers to cross-reference this control across tools, reports, and evidence.
Compliance.tf Control:
sqs_queue_dead_letter_queue_configuredAWS Config Managed Rule:
SQS_QUEUE_DLQ_CHECKPowerpipe Control:
aws_compliance.control.sqs_queue_dead_letter_queue_configured
Last reviewed: 2026-03-09