nats-io/nats-server · error

create retained messages consumer for account %q: %v

Error message

create retained messages consumer for account %q: %v

What it means

The server creates an ephemeral JetStream consumer to drain MQTT retained messages during session/account setup; if createEphemeralConsumer fails the error is wrapped with the account name. This means the internal consumer for the retained messages stream could not be created, so MQTT retained message handling cannot proceed.

Source

Thrown at server/mqtt.go:1604

	// before. Ignore any errors that might arise.
	rmLegacyDurName := mqttRetainedMsgsStreamName + "_" + jsa.id
	jsa.deleteConsumer(mqttRetainedMsgsStreamName, rmLegacyDurName, true)

	// Create a new, uniquely names consumer for retained messages for this
	// server. The prior one will expire eventually.
	ccfg := &CreateConsumerRequest{
		Stream: mqttRetainedMsgsStreamName,
		Config: ConsumerConfig{
			Name:              mqttRetainedMsgsStreamName + "_" + nuid.Next(),
			FilterSubject:     mqttRetainedMsgsStreamSubject + ">",
			DeliverSubject:    rmsubj,
			ReplayPolicy:      ReplayInstant,
			AckPolicy:         AckNone,
			InactiveThreshold: 5 * time.Minute,
		},
	}
	if _, err := jsa.createEphemeralConsumer(ccfg); err != nil {
		return nil, fmt.Errorf("create retained messages consumer for account %q: %v", accName, err)
	}

	// Set this so that on defer we don't cleanup.
	success = true

	return as, nil
}

func (s *Server) mqttDetermineReplicas() int {
	// If not clustered, then replica will be 1.
	if !s.JetStreamIsClustered() {
		return 1
	}
	opts := s.getOpts()
	replicas := 0
	for _, u := range opts.Routes {
		host := u.Hostname()
		// If this is an IP just add one.

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Check consumer limits on the account/stream and prune stale ephemeral consumers
  2. Verify JetStream cluster health (stream and consumer leaders elected) via nats server report jetstream
  3. Retry the MQTT connection once JS is healthy
  4. Inspect logs for the wrapped cause (e.g. 'no responders', 'leader election in progress') and address underlying JS issue

Example fix

// before
nats consumer report $MQTT.rmsgs   # many stale ephemeral consumers
// after
nats consumer rm $MQTT.rmsgs <stale-ephemeral-consumer>
# then reconnect the MQTT client
Defensive patterns

Strategy: retry

Validate before calling

// Check the stream is ready to accept consumers:
js, _ := nc.JetStream()
si, err := js.StreamInfo("$MQTT.rmsgs")
if err == nil && len(si.State.Replicas) > 0 {
    // verify no current leader election in progress
}

Try / catch

if strings.Contains(err.Error(), "create retained messages consumer") {
    // often transient (elections/no responders); retry with backoff
    return retryWithBackoff(reconnectMQTT)
}

Prevention

When it happens

Trigger: Retained messages stream exists but is in a bad state (no responders/leadership); JetStream API request for consumer creation times out; consumer limits reached on the account/stream; stream unavailable mid-creation.

Common situations: Cluster without a healthy JS leader for the stream; account consumer limits exceeded by leaking ephemeral consumers; transient network/raft issues during MQTT connect.

Related errors


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