nats-io/nats-server · error

consumer not found

Error message

consumer not found

What it means

isConsumerHealthy returns this when the consumer assignment exists (older than the 5s grace window) but no local consumer object (*consumer) can be found on this server (mset.lookupConsumer(consumer) returned nil). It means the consumer should be materialized on this server but its runtime state never appeared — a real, persistent gap between the cluster assignment and local state.

Source

Thrown at server/jetstream_cluster.go:1118

	// 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()
	var nrgWerr error
	if node != nil {
		nrgWerr = node.GetWriteErr()
	}
	consumerWerr := o.getWriteErr()
	switch {
	case rc <= 1:
		return nil // No further checks for R=1 consumers

	case node == nil:
		return errors.New("group node missing")

	case oNode == nil:
		// Can happen when the consumer's node is not yet initialized.

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Compare `nats consumer info <stream> <consumer>` against the server's local consumers; if absent but assigned, restart the server to force asset recovery.
  2. Check server logs at startup for consumer recovery errors (filestore corruption, permission issues) and fix the underlying cause.
  3. If the consumer is genuinely gone, delete and recreate it so assignment and runtime state converge.
  4. Check filestore directory for the consumer's directory; restore from backup or remove stale meta state if corrupted.
Defensive patterns

Strategy: validation

Validate before calling

// Check the consumer actually exists before health or operations
_, err := js.ConsumerInfo(streamName, consumerName)
if err != nil {
    // consumer genuinely missing: recreate it
    js.AddConsumer(streamName, &nats.ConsumerConfig{Name: consumerName, ...})
}

Try / catch

// Go: surface persistent absence, do not retry indefinitely
if err := health(); err != nil && strings.Contains(err.Error(), "consumer not found") {
    return fmt.Errorf("consumer %q permanently missing on server: recreate or recover", consumerName)
}

Prevention

When it happens

Trigger: Health check on a non-leader or leader where lookupConsumer(name) is nil and ca.Created is more than 5 seconds in the past — e.g. consumer creation failed locally, the asset recovery skipped it, or the consumer was deleted on the leader without the deletion propagating.

Common situations: A consumer added with replicas>1 whose creation failed on some peers; server restarted into a state where the assignment exists in the meta layer but the filestore consumer state is missing/corrupt; deleting a consumer while a health check runs after the 5s grace period.

Related errors


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