SQS FIFO "The Request Must Contain the Parameter MessageGroupId" and "ContentBasedDeduplication or MessageDeduplicationId", Fixed: Choosing Group IDs, the Silent 5-Minute Drop, Stuck Groups and Lambda

Logeshwaran
—

"The request must contain the parameter MessageGroupId" means you sent a message to an SQS FIFO queue (a name ending in .fifo) without saying which ordered stream it belongs to; every FIFO message needs a MessageGroupId. Its twin, "The queue should either have ContentBasedDeduplication enabled or MessageDeduplicationId provided explicitly," means the message also needs a deduplication ID, or the queue must be set to make one from the message body. The fix for both is two values on the send call itself, not message attributes: MessageGroupId="customer-42" and either MessageDeduplicationId="order-1042" or ContentBasedDeduplication=true on the queue. Here is the trap waiting right after the fix: a FIFO queue silently drops repeats. Send the same deduplication ID, or with content-based deduplication the same body, twice within five minutes, and both sends return success with a message ID, but only one message is ever delivered. In a test, two identical "refresh-prices" messages both got 200 OK; the consumer received one. This page covers both errors in the CLI, Python, Node.js-style SDK calls and SNS, how to choose group IDs that do not serialize your whole app, the blocked-group behavior that looks like a stuck queue, Lambda with FIFO, and the newer standard-queue use of MessageGroupId.

Jake's phone repair shop moved its order notifications to a FIFO queue so that "received," "repairing" and "ready" texts could never arrive out of order. Ethan, his developer friend, changed the queue URL in the sending code, deployed, and every message failed with "must contain the parameter MessageGroupId." He added a group ID; now they failed asking for a deduplication ID. He switched on content-based deduplication, and it worked, until a customer's second repair of the same phone sent an identical "ready" text that never arrived. Jake's question summed up the week: "Why does the careful queue keep losing things?" It wasn't losing them. It was doing exactly what it promises, and this page is the list of promises.

⚡ Quick Answer

• "must contain the parameter MessageGroupId": add MessageGroupId to the send call (a request parameter, not a message attribute). Fix.

• "ContentBasedDeduplication ... or MessageDeduplicationId": pass MessageDeduplicationId, or set ContentBasedDeduplication=true on the queue. Fix.

• Messages "lost" after the fix: same dedup ID (or same body with content-based dedup) within 5 minutes is accepted and silently not delivered. The 5-minute window.

• Queue looks stuck: a message in flight blocks the rest of its group until it is deleted or its visibility timeout ends. Blocked groups.

• Choosing group IDs: one per independent stream (per customer, per order), never one constant for everything. How to choose.

Also: CLI and SDK examples · Lambda with FIFO · SNS FIFO · MessageGroupId on standard queues · fixes by message.

New to SQS? Our plain-English SQS guide explains queues, consumers and visibility timeouts in about ten minutes. You can follow this page without it.

🧭 NEW HERE? READ THESE FIRST

New to SQS, message attributes or Lambda triggers? These five pages give you the words this one uses:

📌 Bookmark this; the group-ID guide and the five-minute window are the parts you will come back for.

What a FIFO queue promises, and why it needs two extra IDs

A standard SQS queue you may already use is fast and nearly unlimited, but it can deliver a message more than once and does not keep order. A FIFO (first in, first out) queue promises the opposite on both counts: order and no duplicates. Each promise needs one piece of information from you, on every message you send:

  • Order needs a group. "In order" only makes sense within a stream: this customer's notifications, this order's status changes. The MessageGroupId names the stream. Messages in one group are delivered strictly in the order sent, one at a time; messages in different groups are independent and can be processed in parallel.
  • No duplicates needs an identity. To recognize a resend, SQS needs to know that two sends are "the same message." The MessageDeduplicationId is that identity. Any message sent with an ID already seen in the last five minutes is accepted and then not delivered.

Leave out the first and SQS refuses the send. Leave out the second and SQS refuses the send unless the queue has content-based deduplication turned on, in which case it makes the ID itself from a SHA-256 hash of the message body (the body only, not its attributes). Three more FIFO rules matter here: the queue name must end in .fifo; you cannot convert a standard queue into a FIFO queue (you create a new one); and FIFO queues take delays only at the queue level, not per message.

Jake: "So the group is the customer, and the dedup ID is the ticket number on each text?"

Ethan: "That's exactly it. Customer keeps their texts in order, and the ticket number stops the same text going out twice. FIFO just refuses to guess either one."

"The request must contain the parameter MessageGroupId": the fix

The full message, in a test against a FIFO queue, was MissingParameter: The request must contain the parameter MessageGroupId. Your fix is to pass MessageGroupId as a parameter of the send call. The most-read question on this error came from someone who put it in MessageAttributes; that does not work, because message attributes are your custom metadata riding along with the body, while the group ID is a parameter SQS itself reads. Our guide to message attributes vs the body covers that distinction.

import boto3
sqs = boto3.client("sqs")
sqs.send_message(
    QueueUrl="https://sqs.us-east-1.amazonaws.com/123456789012/notifications.fifo",
    MessageBody='{"ticket": "R-1042", "status": "ready"}',
    MessageGroupId="customer-42",            # the ordered stream
    MessageDeduplicationId="R-1042-ready",   # the identity of this message
)

A group ID can be up to 128 characters of letters, digits and punctuation. Every message to a FIFO queue needs one, including messages sent in a batch: in send_message_batch, each entry carries its own MessageGroupId and MessageDeduplicationId, and one entry missing them fails that entry. If you see this error after you "just changed the queue URL" from a standard queue to a FIFO queue, that is why: the sending code never needed these values before.

"The queue should either have ContentBasedDeduplication enabled or MessageDeduplicationId provided explicitly"

The full error from the test was InvalidParameterValue: The queue should either have ContentBasedDeduplication enabled or MessageDeduplicationId provided explicitly. You have two ways out, and the choice matters more than it looks:

OptionHowWhen it is rightThe catch
Explicit MessageDeduplicationIdPass a unique ID per logical message (order ID + event)Almost always; you decide what counts as "the same"You must generate a good ID
ContentBasedDeduplication = trueQueue attribute; SQS hashes the bodyBodies are naturally unique (they carry an ID or timestamp)Identical bodies within 5 minutes are dropped silently

Turn on content-based deduplication on an existing queue:

aws sqs set-queue-attributes \
  --queue-url https://sqs.us-east-1.amazonaws.com/123456789012/notifications.fifo \
  --attributes ContentBasedDeduplication=true

An explicit ID always wins: if the queue has content-based deduplication and you also pass MessageDeduplicationId, your ID is used. The ID can be up to 128 characters. A good one describes the business event, not the attempt: R-1042-ready (this ticket became ready), not a random UUID per send. A random ID per send defeats deduplication, because a retry after a network glitch gets a new ID and goes through twice.

The five-minute window: when FIFO "loses" a message

This is the behavior behind most "my FIFO queue drops messages" reports you will find, and it is the queue working as designed. SQS's own definition: a message sent with a deduplication ID that was already used in the last five minutes is accepted successfully but not delivered. The send returns HTTP 200 and a message ID. Nothing errors. The message simply never reaches a consumer.

The test that shows it: a FIFO queue with content-based deduplication, and the body refresh-prices sent twice in a row. Both calls returned success with different message IDs; a receive right after returned exactly one message. With content-based deduplication, "the same" means "the same body," so any message whose body repeats is at risk: periodic "refresh" or "ping" commands, a status text that is identical for two customers' tickets, a retry of the same payload.

Your fixes are about identity:

  • Put something unique in the deduplication ID that distinguishes events you want delivered: the ticket ID plus the status plus the event time, or a job run ID.
  • Or put it in the body, if you rely on content-based deduplication: include the ticket ID or a timestamp so two different events never hash the same.
  • Keep the same ID only for true retries, which is the point: a send that timed out and is sent again within five minutes with the same ID will not double-deliver. Our guide to messages arriving twice covers the standard-queue side of duplicates.

Jake: "So the second 'your phone is ready' text looked identical to the one from last week's repair, and the queue thought it was a repeat?"

Ethan: "Within five minutes, yes. Same customer re-booked a quick fix. Now the ID has the ticket number in it, and two tickets are never 'the same message.'"

"My FIFO queue is stuck": blocked message groups

FIFO keeps order by never handing out the next message in a group while an earlier one is still being worked on. In the test: three messages in group A and one in group B; consumer 1 received A-0 and did not delete it yet; consumer 2 then asked for up to ten messages and got only B-0. A-1 and A-2 stayed invisible behind A-0.

That is how ordering is guaranteed, and it is also why your FIFO queue can look frozen to you. A group stays blocked until the in-flight message is deleted, or its visibility timeout runs out and it becomes available again (to be retried, still first in line). If a message keeps failing, it blocks its whole group for every retry. The tools:

  • Delete messages promptly after processing, and set the visibility timeout a little longer than your real processing time, not hours.
  • Add a dead-letter queue with a sensible maxReceiveCount, so a poison message leaves the group after a few tries and the rest can flow. A FIFO queue's dead-letter queue must also be FIFO. Our dead-letter queue guide walks through it.
  • Use many groups, so one blocked group holds up one customer, not everyone (next section).

You also cannot ask SQS for "only group A." ReceiveMessage has no group filter; asking for the MessageGroupId attribute only labels what you received. If different groups need different consumers, they belong in different queues. And if messages sit in the queue but never arrive at all, regardless of groups, our messages-not-received guide covers the other causes.

Choosing group IDs that do not serialize your app

The single most common FIFO design mistake you can make is a constant group ID: MessageGroupId="1" or "default" on every message, because the error said a group was required. That makes the whole queue one stream. Every message waits for the one before it, one consumer works at a time, and throughput collapses to whatever one consumer can do serially.

Pick your group at the level where order actually matters to you, which is almost always smaller than "everything":

WorkloadGood MessageGroupIdWhy
Customer notificationscustomer IDEach customer's texts in order; customers in parallel
Order status changesorder IDPaid before shipped, per order
Account balance updatesaccount IDOrdering only matters within one account
Inventory per productSKU or warehouse + SKUStock moves in order per item
Truly global sequenceone constant IDOnly when one strict sequence is the requirement; accept low throughput

Jake: "So if we used one group for the whole shop, every customer would queue behind every other customer?"

Ethan: "Like one till for the whole street. With a group per customer, each customer gets their own till, and each one's texts still come out in order."

There is no limit on the number of groups in a FIFO queue, and more groups mean more messages available to your consumers at once, so the way to scale a FIFO queue is a granular business dimension and many groups. For high-volume FIFO queues, also turn on high throughput mode, which raises the per-queue request limits; its capacity also grows with the number of groups.

Sending to FIFO from the CLI and other SDKs

The AWS CLI: the two values are flags on send-message. The second most-read question on this topic is a CLI send that had --message-group-id but not a deduplication ID:

aws sqs send-message \
  --queue-url https://sqs.us-east-1.amazonaws.com/123456789012/notifications.fifo \
  --message-body '{"ticket":"R-1042","status":"ready"}' \
  --message-group-id customer-42 \
  --message-deduplication-id R-1042-ready

Other SDKs use the same two field names on the send request itself: MessageGroupId and MessageDeduplicationId on SendMessageCommand input in JavaScript v3, .messageGroupId() and .messageDeduplicationId() on the Java v2 request builder, and properties of SendMessageRequest in .NET. Frameworks that wrap SQS (Laravel queues, Spring Cloud AWS, Celery) usually need a setting or a FIFO-aware driver to pass them; check the framework's FIFO option before assuming it sends a group ID for you.

To create a FIFO queue correctly from the start, the name and the attribute go together; a name without .fifo fails with "Queue name must end in .fifo for FIFO queues":

aws sqs create-queue --queue-name notifications.fifo \
  --attributes FifoQueue=true,ContentBasedDeduplication=false,VisibilityTimeout=60

One more FIFO-only rejection: per-message delays. Passing DelaySeconds on a FIFO send fails with "Value 5 for parameter DelaySeconds is invalid. Reason: The request include parameter that is not valid for this queue type." Set DelaySeconds on the queue instead, or schedule the send.

Lambda with a FIFO queue

A Lambda function triggered by a FIFO queue receives messages in order within each group; a batch can mix groups but keeps each group's order. If the function throws an error, Lambda retries the affected messages, and it does not hand that function any newer messages from the same group until those retries are done, which is the blocked-group behavior again, now at the trigger level. Two settings keep that under your control:

  1. A dead-letter queue on the source queue with a small maxReceiveCount, so a message that always fails leaves the group instead of blocking it forever.
  2. Partial batch responses (ReportBatchItemFailures), with one FIFO-specific rule: stop processing at the first failure and return that message and every message after it in the batch as failed. Processing later messages after a failure would break their group's order.
def handler(event, context):
    failures = []
    for i, record in enumerate(event["Records"]):
        try:
            process(record)                 # your work
        except Exception:
            # FIFO: report this one and everything after it, in order
            failures = [{"itemIdentifier": r["messageId"]} for r in event["Records"][i:]]
            break
    return {"batchItemFailures": failures}

If the function cannot read the queue at all, that is a permissions problem, covered in our Lambda and SQS AccessDenied guide.

SNS FIFO topics in front of SQS FIFO

An SNS FIFO topic (name ending in .fifo) fans out ordered messages to SQS FIFO queues, and it has the same two requirements: publishing needs a MessageGroupId, and a MessageDeduplicationId unless the topic has content-based deduplication. SNS passes the group ID through to the subscribed queues, so ordering per group holds end to end. A standard SNS topic cannot deliver to a FIFO queue; both ends must be FIFO.

From the CLI, the flags match the SQS ones:

aws sns publish \
  --topic-arn arn:aws:sns:us-east-1:123456789012:repair-events.fifo \
  --message '{"ticket":"R-1042","status":"ready"}' \
  --message-group-id customer-42 \
  --message-deduplication-id R-1042-ready

If your subscribed queue receives nothing, check the queue's access policy allows the topic to send; that is the most common fan-out failure, and it fails silently on the SNS side.

MessageGroupId on standard queues: fair queues

If you remember MessageGroupId being rejected on standard queues, that changed. Standard queues now accept it to enable fair queues: the group ID identifies a tenant (a customer, a client app, a request type), and SQS keeps one noisy tenant from delaying everyone else's messages. Unlike FIFO, messages with the same group ID on a standard queue are still processed in parallel; there is no ordering and no blocking. In the test, a standard queue accepted a send with MessageGroupId="tenant-1" without complaint. So the same field means "ordered stream" on a FIFO queue and "whose message is this" on a standard one.

The ten-minute fix order

  1. Confirm the queue is FIFO (name ends in .fifo); the error only happens there.
  2. Add MessageGroupId as a send parameter, chosen per independent stream, never a constant for everything.
  3. Add MessageDeduplicationId describing the business event, or turn on content-based deduplication if bodies are unique.
  4. If messages "vanish," check for repeated IDs or bodies within five minutes.
  5. If the queue "sticks," look for an in-flight message holding its group; add a dead-letter queue and delete messages promptly.
  6. With Lambda, return partial batch failures from the first failure onward.

Fixes by message

You seeDo this
The request must contain the parameter MessageGroupIdPass MessageGroupId on the send call (not as an attribute)
ContentBasedDeduplication enabled or MessageDeduplicationId providedPass MessageDeduplicationId, or enable content-based dedup
Queue name must end in .fifo for FIFO queuesName the queue NAME.fifo
DelaySeconds ... not valid for this queue typeSet DelaySeconds on the queue, not per message
Send succeeds, message never arrivesSame dedup ID or body within 5 minutes; make IDs event-specific
Only some messages delivered, queue looks stuckIn-flight message blocks its group; delete faster, add a DLQ
FIFO queue is slowConstant group ID; use per-customer or per-order groups, high throughput mode
Need to convert a standard queueNot possible; create a new .fifo queue and switch senders

Frequently asked questions about SQS FIFO MessageGroupId

What does "The request must contain the parameter MessageGroupId" mean?

You sent a message to an SQS FIFO queue without a MessageGroupId. Every FIFO message must name its group. Add MessageGroupId as a parameter of the send call.

How do I fix "The queue should either have ContentBasedDeduplication enabled or MessageDeduplicationId provided explicitly"?

Pass a MessageDeduplicationId with each message, or set the queue attribute ContentBasedDeduplication to true so SQS hashes the message body into an ID.

Is MessageGroupId a message attribute?

No. It is a parameter of SendMessage, alongside MessageBody. Putting it in MessageAttributes does not set it, and the send still fails.

What should I use as a MessageGroupId?

The unit where order matters: a customer ID, order ID or account ID. Avoid one constant value for every message, which turns the queue into a single slow stream.

What is the difference between MessageGroupId and MessageDeduplicationId?

MessageGroupId says which ordered stream a message belongs to. MessageDeduplicationId says which message it is, so resends within five minutes are not delivered twice.

Why is my FIFO message not delivered even though SendMessage succeeded?

Its deduplication ID, or its body with content-based deduplication, matched a message sent in the last five minutes. SQS accepts duplicates and silently does not deliver them.

How long is the SQS FIFO deduplication interval?

Five minutes. Within it, a repeated deduplication ID is accepted but not delivered. After it, the same ID is treated as a new message.

What does ContentBasedDeduplication do?

SQS generates the deduplication ID from a SHA-256 hash of the message body, not its attributes. Identical bodies within five minutes count as duplicates.

Why is my SQS FIFO queue stuck?

A message from a group is in flight and not yet deleted, so later messages in that group wait. Delete messages after processing, keep the visibility timeout short, and add a dead-letter queue.

Can I receive messages for one MessageGroupId only?

No. ReceiveMessage cannot filter by group. Requesting the MessageGroupId attribute only labels returned messages. Use separate queues for separate consumers.

Can I convert a standard SQS queue to FIFO?

No. Create a new queue whose name ends in .fifo with FifoQueue=true, then switch your senders and consumers to it.

Can I set DelaySeconds per message in a FIFO queue?

No. FIFO queues support delays only at the queue level. A per-message DelaySeconds fails as not valid for this queue type.

How many message groups can a FIFO queue have?

There is no limit. More groups let more messages be processed in parallel while each group stays in order.

Can I use MessageGroupId with a standard SQS queue?

Yes, now. On standard queues it enables fair queues, identifying the tenant so one busy tenant does not delay others. Messages are not ordered or blocked as they are in FIFO.

How does Lambda handle errors with a FIFO queue?

Lambda retries the failed messages before delivering newer ones from the same group. With partial batch responses, stop at the first failure and return it and all later messages as failed.

Does SNS FIFO need a MessageGroupId?

Yes. Publishing to an SNS FIFO topic needs a MessageGroupId and a deduplication ID unless content-based deduplication is on. SNS passes the group to subscribed SQS FIFO queues.

How many in-flight messages can a FIFO queue have?

Up to 120,000 messages received but not yet deleted. At that point SQS returns no error but processing slows; AWS Support can raise it.

Do I need a dedup ID with send_message_batch?

Yes, per entry. Each entry in a FIFO batch needs its own MessageGroupId and MessageDeduplicationId, unless the queue has content-based deduplication.

πŸ“š ALSO READ

Where to go next, from duplicate deliveries to dead-letter queues and message size:

📌 Bookmark this; the group-ID guide and the five-minute window are the parts you will come back for.

The shop's notifications now use the customer ID as the group and the ticket, status and time as the deduplication ID. Texts arrive in order, repeats from retries stay away, and two repairs of the same phone in one afternoon both get their "ready" message. Jake asked whether the careful queue had finally stopped losing things. "It never lost anything," said Ethan. "We just had to tell it which messages were really the same."

📌 If you keep one line from this page

Every FIFO message needs a group (which ordered stream) and an identity (which message): pick the group per customer or order, make the deduplication ID describe the business event, and remember a repeat within five minutes is accepted and never delivered.

Parameters, not attributes · name ends .fifo · no per-message delay · in-flight message blocks its group · Lambda: fail from the first error onward.

Revision note. Written October 16, 2026, with every error message and both silent behaviors reproduced in a test queue. "First come, first served," as the saying goes; FIFO just insists on knowing who came, and whether they came before.

Related