nats-io/nats-server · error

invalid stream update response: missing stream info

Error message

invalid stream update response: missing stream info

What it means

Same class as the create variant but for stream updates: the JSApiStreamUpdateResponse came back without an error but also without StreamInfo, which the server requires to continue (it keeps the updated si). The response is treated as invalid.

Source

Thrown at server/mqtt.go:1851

	}
	return scr.StreamInfo, scr.DidCreate, nil
}

func (jsa *mqttJSA) updateStream(cfg *StreamConfig) (*StreamInfo, error) {
	cfgb, err := json.Marshal(cfg)
	if err != nil {
		return nil, err
	}
	scri, err := jsa.newRequest(mqttJSAStreamUpdate, fmt.Sprintf(JSApiStreamUpdateT, cfg.Name), 0, cfgb)
	if err != nil {
		return nil, err
	}
	scr := scri.(*JSApiStreamUpdateResponse)
	if err = scr.ToError(); err != nil {
		return nil, err
	}
	if scr.StreamInfo == nil {
		return nil, fmt.Errorf("invalid stream update response: missing stream info")
	}
	return scr.StreamInfo, nil
}

func (jsa *mqttJSA) lookupStream(name string) (*StreamInfo, error) {
	slri, err := jsa.newRequest(mqttJSAStreamLookup, fmt.Sprintf(JSApiStreamInfoT, name), 0, nil)
	if err != nil {
		return nil, err
	}
	slr := slri.(*JSApiStreamInfoResponse)
	if err = slr.ToError(); err != nil {
		return nil, err
	}
	if slr.StreamInfo == nil {
		return nil, NewJSStreamNotFoundError()
	}
	return slr.StreamInfo, nil
}

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Align all cluster nodes to the same NATS Server version before running MQTT workloads
  2. Retry the MQTT session setup; the update will be re-attempted
  3. Verify nothing intercepts internal $JS.API subjects (no mirroring/leaf-node rewrite of JS API)
  4. Capture debug logs and report upstream if it reproduces consistently
Defensive patterns

Strategy: retry

Validate before calling

// Verify stream updates round-trip correctly before MQTT migration:
js, _ := nc.JetStream()
si, err := js.UpdateStream(&nats.StreamConfig{Name: "smoke-test", Subjects: []string{"x"}})
if err != nil || si == nil { /* JS update path broken */ }

Type guard

func hasStreamInfoUpd(scr *JSApiStreamUpdateResponse) bool { return scr != nil && scr.StreamInfo != nil }

Try / catch

if strings.Contains(err.Error(), "invalid stream update response") {
    // retry; if persistent, check mixed-version cluster before further updates
    return retryOnceElseCheckVersions(op)
}

Prevention

When it happens

Trigger: JS API stream update succeeded per ToError but response carried no StreamInfo — protocol/shape mismatch between server versions, malformed internal response, or an interceptor mangling $JS.API.STREAM.UPDATE replies.

Common situations: Rolling upgrades with mixed versions issuing internal stream updates (e.g. the MQTT retained stream MaxMsgsPer migration); corrupted responses under load.

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/473307174e277fca. Report an issue: GitHub.