{"record":{"id":"443048c6cb7c33f3","repo":"nats-io/nats-server","slug":"create-qos2-incoming-messages-stream-for-account","errorCode":null,"errorMessage":"create QoS2 incoming messages stream for account %q: %v","messagePattern":"create QoS2 incoming messages stream for account %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mqtt.go","lineNumber":1466,"sourceCode":"\tif si, err := lookupStream(mqttQoS2IncomingMsgsStreamName, \"QoS2 incoming messages\"); 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. Subject is\n\t\t// \"$MQTT.qos2.<session>.<PI>\", the .PI is to achieve exactly\n\t\t// once for each PI.\n\t\tcfg := &StreamConfig{\n\t\t\tName:          mqttQoS2IncomingMsgsStreamName,\n\t\t\tSubjects:      []string{mqttQoS2IncomingMsgsStreamSubjectPrefix + \">\"},\n\t\t\tStorage:       FileStorage,\n\t\t\tRetention:     LimitsPolicy,\n\t\t\tDiscard:       DiscardNew,\n\t\t\tMaxMsgsPer:    1,\n\t\t\tDiscardNewPer: true,\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 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)","sourceCodeStart":1448,"sourceCodeEnd":1484,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/mqtt.go#L1448-L1484","documentation":"For MQTT QoS2, each in-flight message gets its own subject in the QoS2 incoming-messages stream, configured with DiscardNew, MaxMsgsPer=1 and DiscardNewPer. If creating this stream fails for reasons other than it already existing (JSStreamNameExistErr), the error is wrapped with the account name and returned, aborting the MQTT session setup.","triggerScenarios":"jsa.createStream(cfg) for the '<account>-mqtt-q2' stream returns an error other than JSStreamNameExistErr — e.g. account JS limits reject the per-subject discard configuration, storage limits hit, or JS API/permissions errors.","commonSituations":"Older/limited JS tiers that don't support DiscardNewPer; account max-streams quota reached; storage exhausted; JS temporarily unavailable.","solutions":["Check the wrapped inner error for the exact JS cause.","Ensure the NATS server/JS version supports DiscardNewPer (upgrade if running an older JS tier).","Raise the account's stream count/storage limits.","Confirm JetStream health and permissions for the account."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Verify server/JS version supports DiscardNewPer before using QoS2 MQTT\nif (serverInfo.proto < MIN_PROTO_DISCARD_NEW_PER) {\n  throw new Error('upgrade NATS server: QoS2 stream config requires newer JetStream');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await mqttConnect();\n} catch (e) {\n  if (/create QoS2 incoming messages stream/.test(e.message)) {\n    if (/discard|config/.test(e.message)) upgradeServer();\n    else raiseAccountLimits();\n    return mqttConnect();\n  }\n  throw e;\n}","preventionTips":["Run a NATS server version supporting per-subject discard limits","Keep the account under max-stream quotas","Watch for JS API errors when enabling QoS2 workloads","Test QoS2 flows against your production JS tier before rollout"],"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"}