nats-io/nats-server · warning

stream assignment or group missing

Error message

stream assignment or group missing

What it means

Returned by jetStream.isStreamHealthy when, in clustered mode, the stream assignment (sa) or its Raft group is nil during a health check. It means the meta layer knows an assignment should exist but the local node has no valid assignment/group record for it, so healthiness cannot be evaluated.

Source

Thrown at server/jetstream_cluster.go:1012

}

// isStreamHealthy will determine if the stream is up to date or very close.
// For R1 it will make sure the stream is present on this server.
func (js *jetStream) isStreamHealthy(acc *Account, sa *streamAssignment) error {
	js.mu.RLock()
	if sa != nil && sa.unsupported != nil {
		js.mu.RUnlock()
		return nil
	}
	s, cc := js.srv, js.cluster
	if cc == nil {
		// Non-clustered mode
		js.mu.RUnlock()
		return nil
	}
	if sa == nil || sa.Group == nil {
		js.mu.RUnlock()
		return errors.New("stream assignment or group missing")
	}
	// Surface any persisted assignment-level error (e.g. failed create on this
	// peer due to account limits) so the health check reflects the broken state
	// instead of falling through to runtime-only checks.
	if sa.err != nil {
		err := sa.err
		js.mu.RUnlock()
		return fmt.Errorf("stream assignment error: %w", err)
	}
	streamName := sa.Config.Name
	node := sa.Group.node
	js.mu.RUnlock()

	// First lookup stream and make sure its there.
	mset, err := acc.lookupStream(streamName)
	if err != nil {
		return errors.New("stream not found")
	}

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Wait for cluster meta to converge and re-run the health check
  2. Verify all servers see consistent meta state (jsz / $SYS calls) and that the stream actually exists in the cluster
  3. Restart the lagging server so it re-syncs the meta Raft log
Defensive patterns

Strategy: retry

Try / catch

// Health check is query-only; retry with backoff on assignment-missing errors
resp, err := healthcheck()
if err != nil && strings.Contains(err.Error(), "stream assignment or group missing") {
    time.Sleep(backoff) // allow meta Raft to converge, then re-check
}

Prevention

When it happens

Trigger: Health check (HEALTHCHECK API or js.isStreamHealthy) runs on a server that has not yet received/applied the stream assignment, or the assignment was just removed, or sa.Group was never populated by the meta controller.

Common situations: Running $JS.API.HEALTHCHECK during cluster formation or right after stream create/delete; a node that is behind on meta Raft log replication; split-brain or newly joined peer before assignment propagation.

Related errors


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