What it means
A consumer group belongs to one stream key: it’s stored inside it. Commands that work through a
group (XREADGROUP, XPENDING, XCLAIM, XAUTOCLAIM, XGROUP SETID, XINFO CONSUMERS…) look
up the stream, then the group, and when either is missing they refuse:
(error) NOGROUP No such key 'orders' or consumer group 'billing' in XREADGROUP with GROUP option
The wording varies by command: XPENDING, XCLAIM and XAUTOCLAIM say
NOGROUP No such key '<stream>' or consumer group '<group>', and XGROUP SETID,
XGROUP CREATECONSUMER and XINFO CONSUMERS say
NOGROUP No such consumer group '<group>' for key name '<stream>'.
Nothing is read or changed. Two group commands don’t complain at all: XACK replies 0 and
XGROUP DESTROY replies 0 for a group that doesn’t exist, so a typo in the group name there goes
unnoticed.
Common causes
- The group was never created.
XREADGROUPdoesn’t create groups; something has to runXGROUP CREATEfirst, and on a fresh server (a new container, a new environment) nothing did. - The stream key was deleted and written again.
DEL,UNLINK, an expiry, aFLUSHDB, or eviction undermaxmemoryremoves the key and every group in it (RENAMEtakes them to the new name). The nextXADDcreates a new, empty stream with no groups, and readers getNOGROUP. - A restart without persistence, or a failover to a replica that hadn’t caught up, so the groups weren’t there.
- A different name: a typo in the stream or group, another key prefix per environment, or a
reader connected to another database number (
SELECT) than the writer.
Trimming isn’t a cause: XTRIM … MAXLEN 0 empties the stream but keeps the key, and its groups.
How to fix it
Check what exists
EXISTS <stream>
TYPE <stream>
XINFO GROUPS <stream>
TYPE should say stream; XINFO GROUPS lists each group with its last-delivered-id and
pending count.
Create the group before reading, every time a worker starts
XGROUP CREATE <stream> <group> $ MKSTREAM
MKSTREAM creates the stream if needed. $ starts the group at the end, so it gets only new
entries; use 0 to have it read everything already in the stream. If the group exists, this replies
BUSYGROUP, which your code can treat as success.
Recover from NOGROUP while running
A reader that gets NOGROUP can create the group (as above) and retry. Entries that were pending in
the old group are gone with it; anything that must not be lost needs its own record outside the
stream.
Keep the stream from disappearing
Don’t set a TTL on a stream that has groups, and don’t delete it to clear it: trim it with
XTRIM <stream> MAXLEN 0 (or MINID) instead, which keeps its groups. Under maxmemory, use a
volatile-* eviction policy with no TTL on streams, or noeviction, so eviction doesn’t pick them.
Reproduce it
Redis 8.10.2 and Valkey 8.1.10 gave the same replies, in database 15 (excerpts):
XGROUP CREATE seo:err:orders mailers $ MKSTREAM
OK
XADD seo:err:orders * id 1
"1791715731000-0"
XREADGROUP GROUP billing worker-1 COUNT 1 STREAMS seo:err:orders >
(error) NOGROUP No such key 'seo:err:orders' or consumer group 'billing' in XREADGROUP with GROUP option
XREADGROUP GROUP mailers worker-1 COUNT 1 STREAMS seo:err:missing >
(error) NOGROUP No such key 'seo:err:missing' or consumer group 'mailers' in XREADGROUP with GROUP option
XPENDING seo:err:orders billing
(error) NOGROUP No such key 'seo:err:orders' or consumer group 'billing'
XGROUP SETID seo:err:orders billing 0
(error) NOGROUP No such consumer group 'billing' for key name 'seo:err:orders'
XACK seo:err:orders billing 0-1
(integer) 0
XGROUP DESTROY seo:err:orders billing
(integer) 0
(The XADD ID is from Redis.) XCLAIM, XAUTOCLAIM, XGROUP CREATECONSUMER and
XINFO CONSUMERS for billing got the NOGROUP forms described above.
The stream deleted and written again:
XGROUP CREATE seo:err:orders mailers $ MKSTREAM
OK
XADD seo:err:orders * id 1
"1791715741356-0"
XTRIM seo:err:orders MAXLEN 0
(integer) 1
EXISTS seo:err:orders
(integer) 1
DEL seo:err:orders
(integer) 1
XADD seo:err:orders * id 2
"1791715741357-0"
XREADGROUP GROUP mailers worker-1 COUNT 1 STREAMS seo:err:orders >
(error) NOGROUP No such key 'seo:err:orders' or consumer group 'mailers' in XREADGROUP with GROUP option
XGROUP CREATE seo:err:orders mailers 0
OK
XREADGROUP GROUP mailers worker-1 COUNT 1 STREAMS seo:err:orders >
1) 1) "seo:err:orders"
2) 1) 1) "1791715741357-0"
2) 1) "id"
2) "2"
After the XTRIM, XINFO GROUPS still listed mailers; after the DEL, it was gone.
In Inlet
The key grid shows each key’s type and, for streams, their latest entries, so you can see whether
the stream is there and holds what you expect. Query tabs take XINFO GROUPS, XGROUP CREATE and
the other stream commands, and show replies as tables. When the server replies NOGROUP, Inlet
shows the message and links to this page.