nats-io/nats-server · warning

stream node missing

Error message

stream node missing

What it means

Returned by jetStream.isStreamHealthy when the stream's in-memory stream object exists but its Raft node (mset.raftNode()) is nil, i.e. the replicated stream has not finished initializing its raft peer. The comment notes this can happen while the stream's node is not yet initialized.

Source

Thrown at server/jetstream_cluster.go:1050

	msetNode := mset.raftNode()
	mset.cfgMu.RLock()
	replicas := mset.cfg.Replicas
	mset.cfgMu.RUnlock()
	var nrgWerr error
	if node != nil {
		nrgWerr = node.GetWriteErr()
	}
	streamWerr := mset.getWriteErr()
	switch {
	case replicas <= 1:
		return nil // No further checks for R=1 streams

	case node == nil:
		return errors.New("group node missing")

	case msetNode == nil:
		// Can happen when the stream's node is not yet initialized.
		return errors.New("stream node missing")

	case node != msetNode:
		s.Warnf("Detected stream cluster node skew '%s > %s'", acc.GetName(), streamName)
		return errors.New("cluster node skew detected")

	case nrgWerr != nil:
		return fmt.Errorf("node write error: %v", nrgWerr)

	case streamWerr != nil:
		return fmt.Errorf("stream write error: %v", streamWerr)

	case !mset.isMonitorRunning():
		return errors.New("monitor goroutine not running")

	case mset.isCatchingUp():
		return errors.New("stream catching up")

	case !node.Healthy():

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Retry the health check after the stream finishes initializing
  2. Poll STREAM.INFO until the stream reports ready before running health checks
  3. If it never initializes, check server logs for raft/asset creation errors and restart the server

Example fix

// before
hc, _ := nc.Request("$JS.API.HEALTHCHECK", nil, time.Second)
// after
waitForStreamReady(nc, stream, 30*time.Second) // poll STREAM.INFO first
hc, _ := nc.Request("$JS.API.HEALTHCHECK", nil, time.Second)
Defensive patterns

Strategy: retry

Validate before calling

// Wait until the replicated stream reports ready before health checks
waitForStream := func(nc *nats.Conn, stream string, timeout time.Duration) error {
    deadline := time.Now().Add(timeout)
    for time.Now().Before(deadline) {
        if _, err := nc.Request(fmt.Sprintf("$JS.API.STREAM.INFO.%s", stream), nil, 2*time.Second); err == nil {
            return nil
        }
        time.Sleep(500 * time.Millisecond)
    }
    return errors.New("stream not ready")
}

Try / catch

if err != nil && strings.Contains(err.Error(), "stream node missing") {
    // transient during init; retry with backoff, alert only if persistent
    time.Sleep(backoff)
    return healthcheck()
}

Prevention

When it happens

Trigger: HEALTHCHECK on an R>1 stream during the window between stream creation and raft node startup, or after the raft node was torn down (e.g. during stream delete/recreate or failed recovery).

Common situations: Querying health immediately after creating a replicated stream; server restart while raft state is reloading; stream recreation race in automation scripts.

Related errors


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