{"record":{"id":"69e5a0729eff05fd","repo":"nats-io/nats-server","slug":"stream-catching-up","errorCode":null,"errorMessage":"stream catching up","messagePattern":"stream catching up","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"server/jetstream_cluster.go","lineNumber":1066,"sourceCode":"\tcase msetNode == nil:\n\t\t// Can happen when the stream's node is not yet initialized.\n\t\treturn errors.New(\"stream node missing\")\n\n\tcase node != msetNode:\n\t\ts.Warnf(\"Detected stream cluster node skew '%s > %s'\", acc.GetName(), streamName)\n\t\treturn errors.New(\"cluster node skew detected\")\n\n\tcase nrgWerr != nil:\n\t\treturn fmt.Errorf(\"node write error: %v\", nrgWerr)\n\n\tcase streamWerr != nil:\n\t\treturn fmt.Errorf(\"stream write error: %v\", streamWerr)\n\n\tcase !mset.isMonitorRunning():\n\t\treturn errors.New(\"monitor goroutine not running\")\n\n\tcase mset.isCatchingUp():\n\t\treturn errors.New(\"stream catching up\")\n\n\tcase !node.Healthy():\n\t\treturn errors.New(\"group node unhealthy\")\n\n\tdefault:\n\t\treturn nil\n\t}\n}\n\n// isConsumerHealthy will determine if the consumer is up to date.\n// For R1 it will make sure the consunmer is present on this server.\nfunc (js *jetStream) isConsumerHealthy(mset *stream, consumer string, ca *consumerAssignment) error {\n\tjs.mu.RLock()\n\tif ca != nil && ca.unsupported != nil {\n\t\tjs.mu.RUnlock()\n\t\treturn nil\n\t}\n\tif mset == nil {","sourceCodeStart":1048,"sourceCodeEnd":1084,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/jetstream_cluster.go#L1048-L1084","documentation":"Returned by jetStream.isStreamHealthy when the replicated stream is still catching up: its Raft node is replaying entries (e.g. after a restart, snapshot restore, or lag) and is not yet up to date with the group. This is a transient 'not yet current' state rather than a fault.","triggerScenarios":"HEALTHCHECK on a server whose raft node is replaying the log / installing a snapshot / catching up after downtime, detected via mset.isCatchingUp().","commonSituations":"Restarted or newly added replica behind the leader; slow disk replaying a large stream; network partition recovery where the follower must resync.","solutions":["Wait for catch-up to finish and re-run the health check; this is normally transient","Reduce lag sources: keep the server connected and disk I/O healthy; consider snapshotting/compaction","If catch-up never completes, check raft group connectivity and restart the lagging node"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"stream catching up\") {\n    // expected after restarts/partitions; poll until caught up\n    time.Sleep(backoff)\n    return healthcheck()\n}","preventionTips":["Expect catching-up errors after server restarts and treat them as non-fatal","Keep large streams on healthy disks so log replay is fast","Use jsz to observe raft lag rather than failing hard on transient catch-up"],"tags":["jetstream","raft","healthcheck","replication"],"backgroundTag":"jetstream-stream-catching-up","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}