{"record":{"id":"f8c0ebae08352010","repo":"nats-io/nats-server","slug":"invalid-stream-create-response-missing-stream-inf","errorCode":null,"errorMessage":"invalid stream create response: missing stream info","messagePattern":"invalid stream create response: missing stream info","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mqtt.go","lineNumber":1832,"sourceCode":"\tcdr := cdri.(*JSApiConsumerDeleteResponse)\n\treturn cdr, cdr.ToError()\n}\n\nfunc (jsa *mqttJSA) createStream(cfg *StreamConfig) (*StreamInfo, bool, error) {\n\tcfgb, err := json.Marshal(cfg)\n\tif err != nil {\n\t\treturn nil, false, err\n\t}\n\tscri, err := jsa.newRequest(mqttJSAStreamCreate, fmt.Sprintf(JSApiStreamCreateT, cfg.Name), 0, cfgb)\n\tif err != nil {\n\t\treturn nil, false, err\n\t}\n\tscr := scri.(*JSApiStreamCreateResponse)\n\tif err = scr.ToError(); err != nil {\n\t\treturn nil, false, err\n\t}\n\tif scr.StreamInfo == nil {\n\t\treturn nil, false, fmt.Errorf(\"invalid stream create response: missing stream info\")\n\t}\n\treturn scr.StreamInfo, scr.DidCreate, nil\n}\n\nfunc (jsa *mqttJSA) updateStream(cfg *StreamConfig) (*StreamInfo, error) {\n\tcfgb, err := json.Marshal(cfg)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tscri, err := jsa.newRequest(mqttJSAStreamUpdate, fmt.Sprintf(JSApiStreamUpdateT, cfg.Name), 0, cfgb)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tscr := scri.(*JSApiStreamUpdateResponse)\n\tif err = scr.ToError(); err != nil {\n\t\treturn nil, err\n\t}\n\tif scr.StreamInfo == nil {","sourceCodeStart":1814,"sourceCodeEnd":1850,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/mqtt.go#L1814-L1850","documentation":"After sending a JS API stream create request, the server decoded the response but its StreamInfo field was nil (and ToError produced no error), so the reply is considered invalid. The server requires StreamInfo on a successful create response; a nil-info response means the JS API replied without the expected payload.","triggerScenarios":"JSApiStreamCreateResponse arrives with DidCreate/error unset and StreamInfo nil — e.g. malformed/empty reply, protocol mismatch between server versions on internal JS API, or a corrupted internal response.","commonSituations":"Mixed-version clusters where internal JS API shapes differ; truncated or malformed internal responses under extreme load; custom/intercepted JS API traffic.","solutions":["Ensure all servers in the cluster run the same NATS Server version","Retry the operation; a single malformed response is often transient","Check for proxies or monitoring tools intercepting internal $JS.API subjects","If reproducible, capture a CORE debug log and report to nats-server maintainers"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Sanity-check internal JS API works at all:\njs, _ := nc.JetStream()\nif _, err := js.AddStream(&nats.StreamConfig{Name: \"smoke-test\"}); err != nil {\n    // investigate JS API layer before MQTT use\n}\njs.DeleteStream(\"smoke-test\")","typeGuard":"func hasStreamInfo(scr *JSApiStreamCreateResponse) bool { return scr != nil && scr.StreamInfo != nil }","tryCatchPattern":"if strings.Contains(err.Error(), \"invalid stream create response\") {\n    // transient/protocol issue: retry once, then check cluster version skew\n    return retryOnceElseInvestigate(op)\n}","preventionTips":["Keep all servers on identical NATS Server versions","Never intercept or proxy internal $JS.API subjects","Enable trace/debug logging when investigating malformed internal responses"],"tags":["jetstream","mqtt","protocol","invalid-response"],"backgroundTag":"invalid-api-response","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}