{"record":{"id":"98c09482c2b20a0a","repo":"slackhq/nebula","slug":"handshake-message-index-d-exceeds-replay-window","errorCode":null,"errorMessage":"handshake message index %d exceeds replay window","messagePattern":"handshake message index (.+?) exceeds replay window","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"connection_state.go","lineNumber":58,"sourceCode":"\tmyCert         cert.Certificate\n\tpeerCert       *cert.CachedCertificate\n\tinitiator      bool\n\tmessageCounter atomic.Uint64\n\twindow         *Bits\n\tdecryptLock    sync.Mutex\n\twriteLock      sync.Mutex\n\t// epoch is this session's sessionEpoch ordinal. Immutable after creation.\n\tepoch uint64\n}\n\n// newConnectionStateFromResult builds a fully-populated ConnectionState from a\n// completed handshake.Result. It seeds messageCounter and the replay window so\n// that the post-handshake message indices already used on the wire don't count\n// as missed traffic in the data plane.\nfunc newConnectionStateFromResult(r *handshake.Result) (*ConnectionState, error) {\n\t// Refuse a MessageIndex too big for the replay window: it can only be a bug, and would spin the seed loop below.\n\tif r.MessageIndex >= ReplayWindow {\n\t\treturn nil, fmt.Errorf(\"handshake message index %d exceeds replay window\", r.MessageIndex)\n\t}\n\n\tci := &ConnectionState{\n\t\tmyCert:    r.MyCert,\n\t\tinitiator: r.Initiator,\n\t\tpeerCert:  r.RemoteCert,\n\t\teKey:      noiseutil.NewCipherState(r.EKey, r.Cipher),\n\t\tdKey:      noiseutil.NewCipherState(r.DKey, r.Cipher),\n\t\twindow:    NewBits(ReplayWindow),\n\t\tepoch:     sessionEpoch.Add(1),\n\t}\n\tci.messageCounter.Add(r.MessageIndex)\n\tfor i := uint64(1); i <= r.MessageIndex; i++ {\n\t\tci.window.Update(nil, i)\n\t}\n\treturn ci, nil\n}\n","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/connection_state.go#L40-L76","documentation":"Replay-protection error raised while seeding a ConnectionState from a completed handshake: a handshake-stage message counter index exceeded the anti-replay window size, meaning the recorded counter values cannot be represented. This indicates a protocol violation or corrupted handshake state rather than normal traffic; the data plane would otherwise silently drop everything.","triggerScenarios":"Thrown at connection_state.go:58 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Treat as a fatal handshake failure and tear down the connection","Check for a buggy or hostile peer sending out-of-range counters","Upgrade both peers to compatible versions if the counter window semantics changed"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}