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

  1. Wait for meta-group convergence: verify all peers see the consumer assignment (jsz API on each server) and re-check health.
  2. Confirm the meta/raft group is healthy (no split brain); fix connectivity between cluster peers (routes) if elections are flapping.
  3. If the consumer should exist, re-issue the consumer create request once the cluster is stable.
  4. 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

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


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/0e5f34d59852c0d5. Report an issue: GitHub.