{"record":{"id":"8548f96f8711e381","repo":"nats-io/nats-server","slug":"could-not-look-up-the-retained-messages-stream-for","errorCode":null,"errorMessage":"could not look up the retained messages stream for account %q","messagePattern":"could not look up the retained messages stream for account %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mqtt.go","lineNumber":1565,"sourceCode":"\t\t// to load all retained messages.\n\t\tsi, err = lookupStream(mqttRetainedMsgsStreamName, \"retained messages\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tneedToTransfer = false\n\t\treturn nil\n\t}\n\n\t// Attempt to transfer all \"single subject\" retained messages to new\n\t// subjects. It may fail, will log its own error; ignore it the first time\n\t// and proceed to updating MaxMsgsPer. Then we invoke transferRMS() again,\n\t// which will get another chance to resolve the error; if not we bail there.\n\tif err = transferRMS(); err != nil {\n\t\treturn nil, err\n\t}\n\t// Guard before dereferencing si.Config below.\n\tif si == nil {\n\t\treturn nil, fmt.Errorf(\"could not look up the retained messages stream for account %q\", accName)\n\t}\n\n\t// Now, if the stream does not have MaxMsgsPer set to 1, and there are no\n\t// more messages on the single $MQTT.rmsgs subject, update the stream again.\n\tif si.Config.MaxMsgsPer != 1 {\n\t\tsi.Config.MaxMsgsPer = 1\n\t\t// We will need an up-to-date si, so don't use local variable here.\n\t\tif si, err = jsa.updateStream(&si.Config); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to update stream config: %w\", err)\n\t\t}\n\t}\n\n\t// If we failed the first time, there is now at most one lingering message\n\t// in the old subject. Try again (it will be a NO-OP if succeeded the first\n\t// time).\n\tif err = transferRMS(); err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":1547,"sourceCodeEnd":1583,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/mqtt.go#L1547-L1583","documentation":"Similar to the nil guard earlier: after the retained-messages transfer step (transferRMS) ran, the server checks si before reading si.Config and found it nil, meaning the stream could not be resolved even after transfer/retry. This indicates the retained messages stream for the account is simply not available.","triggerScenarios":"transferRMS returned success but the lookup inside it still failed to populate si, or the stream was deleted concurrently between creation/update and this check; the retained messages stream does not exist for the account.","commonSituations":"Someone deleted the $MQTT.rmsgs stream while MQTT clients were connected; cluster instability causing lookups to fail; half-completed upgrade/migration of the retained messages stream.","solutions":["Verify the stream exists: nats stream ls and look for the retained messages stream; reconnect MQTT clients so the server recreates it","If the stream was deleted, disconnect/reconnect the MQTT session to trigger recreation","Check cluster/meta health and logs for lookup failures","Ensure no ops scripts delete JetStream streams used internally by the MQTT subsystem"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Confirm the internal stream exists and is healthy:\njs, _ := nc.JetStream()\nsi, err := js.StreamInfo(\"$MQTT.rmsgs\")\nif err == nil {\n    for _, r := range si.State.Replicas { /* check peer lag/health */ }\n}","typeGuard":"func streamAvailable(si *nats.StreamInfo) bool { return si != nil }","tryCatchPattern":"if strings.Contains(err.Error(), \"could not look up the retained messages stream\") {\n    // stream deleted or lookup raced; reconnect to trigger recreation\n    return retryReconnect(ctx)\n}","preventionTips":["Protect internal streams from ops deletion (document $MQTT.* ownership)","Reconnect MQTT clients after any manual stream surgery","Monitor JS stream existence as part of health checks when MQTT is in use"],"tags":["jetstream","mqtt","stream-lookup","nil-guard"],"backgroundTag":"jetstream-stream-not-found","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}