This error occurs when the XREADGROUP command is called without the required GROUP keyword and parameters. XREADGROUP is specifically designed for consumer group operations and mandates explicit group and consumer identification.
The "ERR XREADGROUP requires GROUP option" error is raised by Redis when you attempt to use the XREADGROUP command without providing the mandatory GROUP clause that specifies the consumer group name and consumer name. XREADGROUP is fundamentally different from the basic XREAD command—it's designed for coordinated stream consumption across multiple clients using consumer groups. The GROUP option is not optional; it's a core requirement that tells Redis which consumer group is reading the messages and which specific consumer within that group is performing the read operation. This error typically indicates either a syntax mistake in the command construction, confusion between XREAD and XREADGROUP commands, or misuse of a Redis client library that abstracts the XREADGROUP API. Unlike regular stream reads, consumer group reads track which messages have been delivered to which consumers, enabling reliable distributed processing of stream data.
The XREADGROUP command requires the GROUP keyword followed by the group name and consumer name. The basic syntax is:
XREADGROUP GROUP groupname consumername STREAMS streamkey idExample reading new messages from a consumer group:
XREADGROUP GROUP mygroup consumer1 STREAMS mystream >Example with additional options:
XREADGROUP GROUP mygroup consumer1 COUNT 10 BLOCK 5000 STREAMS mystream >The GROUP keyword must appear immediately after XREADGROUP, followed by your group name and consumer identifier.
Before using XREADGROUP, ensure the consumer group exists. Create it using XGROUP CREATE:
# Create a new consumer group starting from the beginning
XGROUP CREATE mystream mygroup 0
# Create a group starting from the last entry
XGROUP CREATE mystream mygroup $
# Create with MKSTREAM to create the stream if it doesn't exist
XGROUP CREATE mystream mygroup $ MKSTREAMVerify the group exists:
XINFO GROUPS mystreamYou should see your group listed with its consumer count and pending messages.
Ensure you're using your Redis client library's XREADGROUP method correctly with all required parameters:
Node.js (node-redis):
const messages = await client.xReadGroup(
'mygroup', // Group name
'consumer1', // Consumer name
{ key: 'mystream', id: '>' },
{ COUNT: 10, BLOCK: 5000 }
);Python (redis-py):
messages = client.xreadgroup(
groupname='mygroup',
consumername='consumer1',
streams={'mystream': '>'},
count=10,
block=5000
)Go (go-redis):
messages, err := client.XReadGroup(ctx, &redis.XReadGroupArgs{
Group: "mygroup",
Consumer: "consumer1",
Streams: []string{"mystream", ">"},
Count: 10,
Block: 5 * time.Second,
}).Result()Java (Jedis):
List<Entry<String, List<StreamEntry>>> messages = jedis.xreadGroup(
"mygroup",
"consumer1",
1,
5000,
false,
Collections.singletonMap("mystream", StreamEntryID.UNRECEIVED_ENTRY)
);Check your library's documentation for the exact method signature and parameter order.
Don't confuse XREAD with XREADGROUP. They serve different purposes:
XREAD - Simple stream reading without consumer groups:
# No GROUP keyword needed
XREAD STREAMS mystream $XREADGROUP - Consumer group-based reading with delivery tracking:
# GROUP keyword is REQUIRED
XREADGROUP GROUP mygroup consumer1 STREAMS mystream >Use XREAD when:
- Reading streams from a single client
- No need to track which messages were delivered
- Messages don't require acknowledgment
Use XREADGROUP when:
- Multiple consumers need to share work
- Messages must be acknowledged (ACK)
- You need delivery guarantees and message history
- Implementing distributed stream processing
When using XREADGROUP, the special ID > has a specific meaning:
# > means "fetch only new messages never delivered to any consumer"
XREADGROUP GROUP mygroup consumer1 STREAMS mystream >To fetch messages pending for this specific consumer (previously delivered but not ACKed):
# Use 0 instead of >
XREADGROUP GROUP mygroup consumer1 STREAMS mystream 0To fetch from a specific ID onwards:
# Use the actual stream entry ID
XREADGROUP GROUP mygroup consumer1 STREAMS mystream 1609459200000-0The > ID only works with XREADGROUP, not with regular XREAD.
After successfully processing messages from XREADGROUP, acknowledge them with XACK:
# Read messages
XREADGROUP GROUP mygroup consumer1 COUNT 5 STREAMS mystream >
# After processing each message, acknowledge it
XACK mystream mygroup 1609459200000-0
# Or acknowledge multiple messages
XACK mystream mygroup 1609459200000-0 1609459200001-0 1609459200002-0Unacknowledged messages remain in the pending entries list (PEL) and can be reclaimed by other consumers or the same consumer.
Check pending messages:
XPENDING mystream mygroupConsumer Group Architecture: Redis consumer groups enable parallel stream processing by dividing messages among multiple consumers. Each consumer group maintains its own independent cursor position in the stream and tracks which messages have been delivered to which consumers via the Pending Entries List (PEL).
Automatic Consumer Creation: The consumer name specified in XREADGROUP doesn't need to exist beforehand—Redis automatically creates it on first use. However, the consumer GROUP must be created explicitly using XGROUP CREATE before any XREADGROUP calls.
Message Delivery Guarantees: XREADGROUP provides at-least-once delivery semantics. Messages remain in the PEL until explicitly acknowledged with XACK, allowing recovery from consumer failures. If a consumer crashes after reading but before acknowledging, another consumer can claim those messages using XAUTOCLAIM or XCLAIM.
NOACK Option: You can add the NOACK flag to XREADGROUP to skip adding messages to the PEL, effectively providing at-most-once delivery semantics for high-throughput scenarios where message loss is acceptable:
XREADGROUP GROUP mygroup consumer1 NOACK STREAMS mystream >Multiple Stream Reads: XREADGROUP can read from multiple streams simultaneously, just like XREAD. Each stream needs its own ID parameter:
XREADGROUP GROUP mygroup consumer1 STREAMS stream1 stream2 stream3 > > >BLOCK Timeout: When using BLOCK with XREADGROUP, a timeout of 0 means block indefinitely until messages arrive. The GROUP option error occurs during command parsing before any blocking, so timeout values don't affect this particular error.
ERR Unbalanced XREAD list of streams
How to fix "ERR Unbalanced XREAD list" in Redis
ERR syntax error
How to fix "ERR syntax error" in Redis
ConnectionError: Error while reading from socket
ConnectionError: Error while reading from socket in redis-py
ERR unknown command
How to fix ERR unknown command in Redis
Command timed out
How to fix 'Command timed out' in ioredis