{"record":{"id":"a81fd70ba1cd52e5","repo":"nats-io/nats-server","slug":"stream-assignment-or-group-missing","errorCode":null,"errorMessage":"stream assignment or group missing","messagePattern":"stream assignment or group missing","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"server/jetstream_cluster.go","lineNumber":1012,"sourceCode":"}\n\n// isStreamHealthy will determine if the stream is up to date or very close.\n// For R1 it will make sure the stream is present on this server.\nfunc (js *jetStream) isStreamHealthy(acc *Account, sa *streamAssignment) error {\n\tjs.mu.RLock()\n\tif sa != nil && sa.unsupported != nil {\n\t\tjs.mu.RUnlock()\n\t\treturn nil\n\t}\n\ts, cc := js.srv, js.cluster\n\tif cc == nil {\n\t\t// Non-clustered mode\n\t\tjs.mu.RUnlock()\n\t\treturn nil\n\t}\n\tif sa == nil || sa.Group == nil {\n\t\tjs.mu.RUnlock()\n\t\treturn errors.New(\"stream assignment or group missing\")\n\t}\n\t// Surface any persisted assignment-level error (e.g. failed create on this\n\t// peer due to account limits) so the health check reflects the broken state\n\t// instead of falling through to runtime-only checks.\n\tif sa.err != nil {\n\t\terr := sa.err\n\t\tjs.mu.RUnlock()\n\t\treturn fmt.Errorf(\"stream assignment error: %w\", err)\n\t}\n\tstreamName := sa.Config.Name\n\tnode := sa.Group.node\n\tjs.mu.RUnlock()\n\n\t// First lookup stream and make sure its there.\n\tmset, err := acc.lookupStream(streamName)\n\tif err != nil {\n\t\treturn errors.New(\"stream not found\")\n\t}","sourceCodeStart":994,"sourceCodeEnd":1030,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/jetstream_cluster.go#L994-L1030","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Wait for cluster meta to converge and re-run the health check","Verify all servers see consistent meta state (jsz / $SYS calls) and that the stream actually exists in the cluster","Restart the lagging server so it re-syncs the meta Raft log"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Health check is query-only; retry with backoff on assignment-missing errors\nresp, err := healthcheck()\nif err != nil && strings.Contains(err.Error(), \"stream assignment or group missing\") {\n    time.Sleep(backoff) // allow meta Raft to converge, then re-check\n}","preventionTips":["Delay health checks until the server reports cluster meta is caught up","Avoid HEALTHCHECK immediately after stream create/delete operations","Monitor meta group health ($SYS) to distinguish convergence lag from real faults"],"tags":["jetstream","clustering","healthcheck","raft"],"backgroundTag":"jetstream-stream-assignment-missing","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}