nats-io/nats-server · warning
consumer assignment or group missing
Error message
consumer assignment or group missing
What it means
Thrown by isConsumerHealthy when, in clustered mode, there is no consumerAssignment (ca) or the assignment has no raft Group — i.e. the server knows a consumer should exist but has no cluster assignment record for it. This means the meta layer has not yet assigned (or has already removed) the consumer's placement for this server, so its raft group and health cannot be evaluated.
Source
Thrown at server/jetstream_cluster.go:1096
func (js *jetStream) isConsumerHealthy(mset *stream, consumer string, ca *consumerAssignment) error {
js.mu.RLock()
if ca != nil && ca.unsupported != nil {
js.mu.RUnlock()
return nil
}
if mset == nil {
js.mu.RUnlock()
return errors.New("stream missing")
}
s, cc := js.srv, js.cluster
if cc == nil {
// Non-clustered mode
js.mu.RUnlock()
return nil
}
if ca == nil || ca.Group == nil {
js.mu.RUnlock()
return errors.New("consumer assignment or group missing")
}
// Surface any persisted assignment-level error (e.g. failed create on this
// peer) so the health check reflects the broken state instead of falling
// through to runtime-only checks.
if ca.err != nil {
err := ca.err
js.mu.RUnlock()
return fmt.Errorf("consumer assignment error: %w", err)
}
created := ca.Created
node := ca.Group.node
js.mu.RUnlock()
// Check if not running at all.
o := mset.lookupConsumer(consumer)
if o == nil {
if time.Since(created) < 5*time.Second {
// No further checks, consumer is not available yet but should be soon.View on GitHub (pinned to 3a66a489d2)
Solutions
- Wait for meta-group convergence: verify all peers see the consumer assignment (jsz API on each server) and re-check health.
- Confirm the meta/raft group is healthy (no split brain); fix connectivity between cluster peers (routes) if elections are flapping.
- If the consumer should exist, re-issue the consumer create request once the cluster is stable.
- Poll the health endpoint less aggressively during topology changes; the condition is usually transient.
Defensive patterns
Strategy: retry
Validate before calling
// Confirm the consumer assignment is visible before health checks
info, err := js.ConsumerInfo(stream, consumer)
if err != nil || info == nil {
// assignment not yet propagated; wait
}
Try / catch
// Go: back off and retry while cluster converges
err := healthCheck()
for i := 0; err != nil && strings.Contains(err.Error(), "assignment or group missing") && i < 5; i++ {
time.Sleep(time.Duration(1<<i) * time.Second)
err = healthCheck()
} Prevention
- Wait for cluster convergence before health-polling after consumer creation
- Keep meta group connectivity stable (routes) to avoid re-proposals
- Don't poll health aggressively during rolling restarts
- Ensure all peers run compatible NATS server versions
When it happens
Trigger: Health check runs on a server with js.cluster != nil while ca is nil for the requested consumer, or ca.Group == nil — e.g. consumer API request accepted by the leader but the assignment has not propagated to this peer yet, or the assignment was purged during meta recovery.
Common situations: Right after adding a consumer with Replicas > 1 while a replica is still syncing; after a split-brain or meta-controller election where assignments are being re-proposed; during initial cluster formation when /jsz?health=true is polled too aggressively.
Related errors
- stream assignment or group missing
- group node missing
- cluster node skew detected
- stream missing
- consumer not found
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/0e5f34d59852c0d5.
Report an issue: GitHub.