{"record":{"id":"25a03e511619747b","repo":"nats-io/nats-server","slug":"create-qos2-outgoing-pubrel-stream-for-account-q","errorCode":null,"errorMessage":"create QoS2 outgoing PUBREL stream for account %q: %v","messagePattern":"create QoS2 outgoing PUBREL stream for account %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mqtt.go","lineNumber":1484,"sourceCode":"\t\t\treturn nil, fmt.Errorf(\"create QoS2 incoming messages stream for account %q: %v\", accName, err)\n\t\t}\n\t}\n\n\tif si, err := lookupStream(mqttOutStreamName, \"QoS2 outgoing PUBREL\"); err != nil {\n\t\treturn nil, err\n\t} else if si == nil {\n\t\t// Create the stream for the incoming QoS2 messages that have not been\n\t\t// PUBREL-ed by the sender. NATS messages are submitted as\n\t\t// \"$MQTT.pubrel.<session hash>\"\n\t\tcfg := &StreamConfig{\n\t\t\tName:      mqttOutStreamName,\n\t\t\tSubjects:  []string{mqttOutSubjectPrefix + \">\"},\n\t\t\tStorage:   FileStorage,\n\t\t\tRetention: InterestPolicy,\n\t\t\tReplicas:  replicas,\n\t\t}\n\t\tif _, _, err := jsa.createStream(cfg); isErrorOtherThan(err, JSStreamNameExistErr) {\n\t\t\treturn nil, fmt.Errorf(\"create QoS2 outgoing PUBREL stream for account %q: %v\", accName, err)\n\t\t}\n\t}\n\n\t// This is the only case where we need \"si\" after lookup/create\n\tneedToTransfer := true\n\tsi, err := lookupStream(mqttRetainedMsgsStreamName, \"retained messages\")\n\tswitch {\n\tcase err != nil:\n\t\treturn nil, err\n\n\tcase si == nil:\n\t\t// Create the stream for retained messages.\n\t\tcfg := &StreamConfig{\n\t\t\tName:       mqttRetainedMsgsStreamName,\n\t\t\tSubjects:   []string{mqttRetainedMsgsStreamSubject + \">\"},\n\t\t\tStorage:    FileStorage,\n\t\t\tRetention:  LimitsPolicy,\n\t\t\tReplicas:   replicas,","sourceCodeStart":1466,"sourceCodeEnd":1502,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/mqtt.go#L1466-L1502","documentation":"MQTT outgoing PUBREL tracking (QoS2 handshake step 2) is persisted in a per-account stream on subjects mqttOutSubjectPrefix + '>' with FileStorage and InterestPolicy. If its creation fails with an error other than JSStreamNameExistErr, this wrapped error names the stream role, account, and underlying JS error, failing the MQTT connection setup.","triggerScenarios":"jsa.createStream(cfg) for the '<account>-mqtt-out' (PUBREL) stream fails with anything other than JSStreamNameExistErr — account JS limits, storage quota, replicas exceeding cluster size, or JS API/permission errors during mqttJSStreamConfig.","commonSituations":"Account JetStream quota exhausted; JS disabled or unhealthy; cluster too small for the configured replicas; storage backend (file) full or misconfigured.","solutions":["Read the wrapped inner error to identify the underlying JetStream failure.","Increase account JS stream/storage limits or free disk space.","Verify cluster size supports the configured StreamReplicas.","Check JetStream status via monitoring and confirm the account has JS enabled."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Pre-flight: account must have JetStream with available streams and storage\nif (!account.jetstream.enabled) throw new Error('enable JetStream for the account before MQTT');","typeGuard":null,"tryCatchPattern":"try {\n  await mqttConnect();\n} catch (e) {\n  if (/create QoS2 outgoing PUBREL stream/.test(e.message)) {\n    // likely JS limits or health; remediate and retry with backoff\n    raiseAccountLimitsOrRestoreJS();\n    return withBackoff(mqttConnect);\n  }\n  throw e;\n}","preventionTips":["Enable JetStream for every account using MQTT","Keep storage and stream-count headroom on the account tier","Match StreamReplicas to actual cluster size","Monitor the '<account>-mqtt-out' stream health in production"],"tags":["mqtt","jetstream","qos2","stream-creation"],"backgroundTag":"jetstream-stream-creation-failed","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}