nats-io/nats-server · error
lookup %s stream for account %q: %v
Error message
lookup %s stream for account %q: %v
What it means
During MQTT JetStream stream setup for an account, mqtt.jsStreamConfig looks up existing streams (messages, sessions, QoS2, retained, etc.) via jsa.lookupStream. If the lookup fails with anything other than JSStreamNotFoundErr, the error is wrapped with the role of the stream (txt) and account name so operators know which stream lookup failed. Stream-not-found is treated as normal (stream will be created), all other lookup errors are fatal here.
Source
Thrown at server/mqtt.go:1397
// Start the go routine that will send JS API requests.
s.startGoRoutine(func() {
defer s.grWG.Done()
as.sendJSAPIrequests(s, c, accName, closeCh)
})
// Start the go routine that will clean up cached retained messages that expired.
s.startGoRoutine(func() {
defer s.grWG.Done()
as.cleanupRetainedMessageCache(s, closeCh)
})
lookupStream := func(stream, txt string) (*StreamInfo, error) {
si, err := jsa.lookupStream(stream)
if err != nil {
if IsNatsErr(err, JSStreamNotFoundErr) {
return nil, nil
}
return nil, fmt.Errorf("lookup %s stream for account %q: %v", txt, accName, err)
}
if opts.MQTT.StreamReplicas == 0 {
return si, nil
}
sr := 1
if si.Cluster != nil {
sr += len(si.Cluster.Replicas)
}
if replicas != sr {
s.Warnf("MQTT %s stream replicas mismatch: current is %v but configuration is %v for '%s > %s'",
txt, sr, replicas, accName, stream)
}
return si, nil
}
if si, err := lookupStream(mqttSessStreamName, "sessions"); err != nil {
return nil, err
} else if si == nil {View on GitHub (pinned to 3a66a489d2)
Solutions
- Read the wrapped inner error after 'lookup ... stream for account' to get the underlying JetStream cause.
- Enable JetStream on the server and grant the account JS permissions and limits.
- Check JetStream cluster health (server logs, jsz) if errors reference raft/metadata.
- Verify the account's JS tier/resource limits aren't exhausted.
Defensive patterns
Strategy: retry
Validate before calling
// Pre-check server/account readiness before connecting MQTT clients
// nats account info: JetStream enabled and resources available
if (!account.jetstream || !account.jetstream.enabled) throw new Error('JetStream required for MQTT'); Try / catch
try {
await mqttConnect();
} catch (e) {
if (/lookup .* stream for account/.test(e.message)) {
// JetStream lookup failed; wait for JS health then retry
await waitForJetStreamHealthy();
return mqttConnect();
}
throw e;
} Prevention
- Enable JetStream on the server and the account before enabling MQTT
- Grant the account JS user permissions and adequate limits
- Monitor JetStream cluster health (jsz) in production
- Align JS domain configuration across servers
When it happens
Trigger: jsa.lookupStream(stream) returns an error that is not JSStreamNotFoundErr — e.g. JetStream not enabled for the account, account JS resources exhausted, API/permission errors, raft/cluster issues — inside the lookupStream closure of mqttJSStreamConfig.
Common situations: MQTT enabled but JetStream not enabled on the account/server; missing JS permissions for the account; JS storage/account limits reached; cluster instability; misconfigured JS domain.
Related errors
- mqtt: consumer_replicas (%v) cannot be higher than stream_re
- could not look up or create the retained messages stream for
- could not look up the retained messages stream for account %
- system account not setup
- JetStream cluster requires cluster name
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/666d3814e97dc364.
Report an issue: GitHub.