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
- Check consumer limits on the account/stream and prune stale ephemeral consumers
- Verify JetStream cluster health (stream and consumer leaders elected) via nats server report jetstream
- Retry the MQTT connection once JS is healthy
- 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
- Set account consumer limits high enough for MQTT sessions (one ephemeral per session)
- Alert on JS leader elections; pause mass MQTT reconnects during them
- Prune leaked ephemeral consumers regularly
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
- unable to delete consumer %q for session %q: %v
- inactive_threshold must not be negative
- max_request_batch must be set if it's JetStream limits are s
- consumer name can not contain '.', '*', '>', '\', '/'
- consumer durable name can not contain '.', '*', '>', '\', '/
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/07be5eb81b465b90.
Report an issue: GitHub.