nats-io/nats-server · error
consumer assignment error: %w
Error message
consumer assignment error: %w
What it means
During the consumer portion of a JetStream health check, the consumer assignment (ca) carries a persisted assignment-level error (ca.err) — for example the consumer failed to be created on this peer (limits, invalid config). The health check surfaces this error instead of falling through to runtime checks on a consumer that never started, so the consumer reports unhealthy.
Source
Thrown at server/jetstream_cluster.go:1104
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.
// We'll start erroring once we're sure this consumer is actually broken.
return nil
}
return errors.New("consumer not found")
}
oNode := o.raftNode()
rc, _ := o.replica()View on GitHub (pinned to 3a66a489d2)
Solutions
- Unwrap the error to see the root cause (limits, invalid config) and fix it — e.g. delete unused consumers to free MaxConsumers quota, correct the consumer config
- Re-issue the consumer create/update via the JS API so the assignment error clears
- Check that all peers run compatible server versions for the consumer features used
- Review server logs on the peer that originally rejected the consumer for the exact failure reason
Defensive patterns
Strategy: try-catch
Validate before calling
ci, err := js.ConsumerInfo(stream, consumer)
if err != nil { /* consumer never materialized: inspect assignment error via healthz/jsz */ }
Type guard
func hasConsumerAssignmentErr(err error) bool {
return strings.Contains(err.Error(), "consumer assignment error")
}
Try / catch
if err := healthz(); err != nil {
cause := errors.Unwrap(err)
log.Printf("consumer assignment unhealthy: %v", cause) // fix root cause (limits/config)
}
Prevention
- Track MaxConsumers usage and clean up idle/ephemeral consumers
- Validate consumer configs against the server version in use
- Re-issue consumer creation after cluster partitions to clear stale assignment errors
When it happens
Trigger: Consumer create/update proposal failed on a peer and the error was persisted in the consumer assignment; consumer created with a config the peer cannot honor (e.g. deliver subject doesn't exist on that server version, account limits); leader election moved to a peer holding the failed assignment.
Common situations: Exceeded MaxConsumers or related account limits; DURABLE consumer config conflict across versions; partially failed consumer creation after network partition during setup.
Related errors
- stream missing
- consumer not found
- consumer node missing
- stream assignment error: %w
- node write error: %v
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/50ce4bee91ea7eac.
Report an issue: GitHub.