nats-io/nats-server · error

create retained messages stream for account %q: %v

Error message

create retained messages stream for account %q: %v

What it means

This error wraps a failure to create the internal JetStream stream that backs MQTT retained messages ($MQTT.rmsgs stream) for an account. The NATS server creates this stream on demand when an MQTT client session is set up; if createStream fails with anything other than 'stream already exists', the original error is wrapped with the account name for context. It indicates a JetStream-level problem preventing stream creation.

Source

Thrown at server/mqtt.go:1509

	switch {
	case err != nil:
		return nil, err

	case si == nil:
		// Create the stream for retained messages.
		cfg := &StreamConfig{
			Name:       mqttRetainedMsgsStreamName,
			Subjects:   []string{mqttRetainedMsgsStreamSubject + ">"},
			Storage:    FileStorage,
			Retention:  LimitsPolicy,
			Replicas:   replicas,
			MaxMsgsPer: 1,
		}
		// We will need "si" outside of this block.
		si, _, err = jsa.createStream(cfg)
		if err != nil {
			if isErrorOtherThan(err, JSStreamNameExistErr) {
				return nil, fmt.Errorf("create retained messages stream for account %q: %v", accName, err)
			}
			// Suppose we had a race and the stream was actually created by another
			// node, we really need "si" after that, so lookup the stream again here.
			si, err = lookupStream(mqttRetainedMsgsStreamName, "retained messages")
			if err != nil {
				return nil, err
			}
		}
		needToTransfer = false

	default:
		needToTransfer = si.Config.MaxMsgsPer != 1
	}
	// Guard before dereferencing si.Config below.
	if si == nil {
		return nil, fmt.Errorf("could not look up or create the retained messages stream for account %q", accName)
	}

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Enable JetStream (remove --js disabled / set jetstream {} in config) or verify the account has JetStream enabled
  2. Check server logs for the wrapped underlying error (e.g. no resources, low storage) and free disk/memory or raise resource limits
  3. Check for a pre-existing conflicting stream named for retained messages with an incompatible config and delete/recreate it
  4. Restart the server / retry connection once JetStream is healthy

Example fix

// before (server config)
// jetstream disabled
// after
jetstream {
  store_dir: "/data/nats"
  max_memory_store: 1GB
  max_file_store: 10GB
}
Defensive patterns

Strategy: validation

Validate before calling

// Before connecting MQTT clients, verify JetStream is enabled and healthy:
nc, _ := nats.Connect(url)
js, _ := nc.JetStream()
_, err := js.AccountInfo()
if err != nil {
    // JetStream unavailable: enable it in server config before MQTT use
    log.Fatalf("JetStream not available: %v", err)
}

Try / catch

if err != nil {
    if strings.Contains(err.Error(), "create retained messages stream") {
        // check JetStream status, then retry with backoff
        retryWithBackoff(func() error { return reconnectMQTT() })
    }
}

Prevention

When it happens

Trigger: JetStream disabled or not ready on the server; an existing stream with the same name but incompatible config; JetStream API request failing (e.g. storage resources unavailable, insufficient resources); internal JSAPI request timeout when creating the retained-messages stream during MQTT session/account setup.

Common situations: Running an MQTT client against a server where JetStream is not enabled; disk full or storage limits hit so the stream cannot be created; cluster where the JS API request times out; misconfigured stream limits in server config.

Related errors


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