What it means
A Redis stream can have consumer groups: named readers that share out its entries and remember
which ones they’ve delivered. You create one with XGROUP CREATE <stream> <group> <id>. If the
stream already has a group of that name, Redis refuses:
(error) BUSYGROUP Consumer Group name already exists
Nothing changes. The existing group keeps its position (last-delivered-id), its consumers and its
pending entries; XGROUP CREATE never resets them, even with a different start ID.
In almost every case, this isn’t a problem to fix but a reply to expect: the group you wanted is there.
Common causes
- Creating the group at start-up. A common pattern is for each worker to run
XGROUP CREATE … MKSTREAMevery time it starts, so it works on a fresh server. From the second start on, the group exists. - Several workers starting at once, each trying to create the same group: one wins, the rest
get
BUSYGROUP. - Expecting
XGROUP CREATEto reset a group to a new starting point. It doesn’t; that’sXGROUP SETID.
How to fix it
Treat BUSYGROUP as success
Create the group at start-up as before, and when the reply is an error whose message starts with
BUSYGROUP, carry on as if it had replied OK:
XGROUP CREATE <stream> <group> $ MKSTREAM
Check for that code rather than ignoring every error: a WRONGTYPE (the key isn’t a stream) or a
lost connection still needs attention. Client libraries pass server errors on as exceptions or error
values carrying the message, so the check is a comparison of its first word.
Or check first
XINFO GROUPS <stream>
lists each group with its consumers, pending, last-delivered-id and lag. If the group is
there, skip XGROUP CREATE. Checking first still leaves a race between two workers starting at
once, so keep the BUSYGROUP check too.
Move an existing group, if that’s what you wanted
XGROUP SETID <stream> <group> $ # deliver only entries added from now
XGROUP SETID <stream> <group> 0 # deliver everything again
Entries already delivered and not acknowledged stay pending either way.
Use MKSTREAM when the stream may not exist
Without MKSTREAM, creating a group on a missing stream fails differently:
ERR The XGROUP subcommand requires the key to exist. Note that for CREATE you may want to use the MKSTREAM option to create an empty stream automatically.
MKSTREAM creates an empty stream if needed, so one call works on a fresh server and on one that
already has the stream.
Reproduce it
Redis 8.10.2 and Valkey 8.1.10 gave the same replies, in database 15:
XGROUP CREATE seo:err:orders mailers $
(error) ERR The XGROUP subcommand requires the key to exist. Note that for CREATE you may want to use the MKSTREAM option to create an empty stream automatically.
XGROUP CREATE seo:err:orders mailers $ MKSTREAM
OK
XGROUP CREATE seo:err:orders mailers $ MKSTREAM
(error) BUSYGROUP Consumer Group name already exists
XGROUP CREATE seo:err:orders mailers 0
(error) BUSYGROUP Consumer Group name already exists
XINFO GROUPS seo:err:orders
1) 1) "name"
2) "mailers"
3) "consumers"
4) (integer) 0
5) "pending"
6) (integer) 0
7) "last-delivered-id"
8) "0-0"
9) "entries-read"
10) (nil)
11) "lag"
12) (integer) 0
The second XGROUP CREATE, with a different start ID, didn’t move the group. In a second test, a
worker read one entry through the group without acknowledging it; XGROUP SETID … $ replied OK,
and XPENDING still counted the entry as pending (1) (integer) 1). On a key holding a
string, XGROUP CREATE … $ got WRONGTYPE Operation against a key holding the wrong kind of value.
In Inlet
The key grid shows streams with their type and latest entries, and query tabs take redis-cli
commands, so XINFO GROUPS and XGROUP run there and show as tables. When the server replies
BUSYGROUP, Inlet shows the message and links to this page.