{"record":{"id":"f171a51d979b62a7","repo":"nats-io/nats-server","slug":"expected-first-catchup-entry-to-be-a-snapshot-and","errorCode":null,"errorMessage":"Expected first catchup entry to be a snapshot and peerstate, will retry","messagePattern":"Expected first catchup entry to be a snapshot and peerstate, will retry","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/raft.go","lineNumber":4749,"sourceCode":"\t\t\t\tn.cancelCatchup()\n\t\t\t}\n\t\t\t// Intentionally not responding. Otherwise, we could erroneously report \"success\". Reporting\n\t\t\t// non-success is not needed either, and would only be wasting messages.\n\t\t\t// For example, if we got partial catchup, and then the \"real-time\" messages came in very delayed.\n\t\t\t// If we reported \"success\" on those \"real-time\" messages, we'd wrongfully be providing\n\t\t\t// quorum while not having an up-to-date log.\n\t\t\tn.Unlock()\n\t\t\treturn\n\t\t}\n\n\t\t// Check if we are catching up. If we are here we know the leader did not have all of the entries\n\t\t// so make sure this is a snapshot entry. If it is not start the catchup process again since it\n\t\t// means we may have missed additional messages.\n\t\tif catchingUp {\n\t\t\t// This means we already entered into a catchup state but what the leader sent us did not match what we expected.\n\t\t\t// Snapshots and peerstate will always be together when a leader is catching us up in this fashion.\n\t\t\tif len(ae.entries) != 2 || ae.entries[0].Type != EntrySnapshot || ae.entries[1].Type != EntryPeerState {\n\t\t\t\tn.warn(\"Expected first catchup entry to be a snapshot and peerstate, will retry\")\n\t\t\t\tn.cancelCatchup()\n\t\t\t\tn.Unlock()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif ps, err := decodePeerState(ae.entries[1].Data); err == nil {\n\t\t\t\tn.processPeerState(ps)\n\t\t\t\t// Also need to copy from client's buffer.\n\t\t\t\tae.entries[0].Data = copyBytes(ae.entries[0].Data)\n\t\t\t} else {\n\t\t\t\tn.warn(\"Could not parse snapshot peerstate correctly\")\n\t\t\t\tn.cancelCatchup()\n\t\t\t\tn.Unlock()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Inherit state from appendEntry with the leader's snapshot.\n\t\t\thadPreviousSnapshot := n.snapfile != _EMPTY_","sourceCodeStart":4731,"sourceCodeEnd":4767,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/raft.go#L4731-L4767","documentation":"During catchup, the first entry received was not the expected snapshot+peerstate pair, meaning real-time or out-of-order messages arrived instead of the catchup head. No response is sent (deliberately, to avoid falsely reporting success), and the catchup process restarts to re-request from a consistent point.","triggerScenarios":"Thrown at server/raft.go:4749 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["No action needed; the automatic retry re-establishes catchup","Frequent retries suggest message reordering or leader churn — check cluster stability","Ensure leaders are not flapping during heavy catchup traffic"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}