{"record":{"id":"f28744b055af7d3c","repo":"slackhq/nebula","slug":"noise-readmessage-w","errorCode":null,"errorMessage":"noise ReadMessage: %w","messagePattern":"noise ReadMessage: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"handshake/machine.go","lineNumber":233,"sourceCode":"\tif header.MessageSubType(packet[1]) != m.subtype {\n\t\treturn nil, nil, ErrSubtypeMismatch\n\t}\n\tif m.result.Initiator && m.hs.MessageIndex() == 0 {\n\t\tm.failed = true\n\t\treturn nil, nil, ErrInitiateNotCalled\n\t}\n\n\t// The (eKey, dKey) ordering here is correct for IX, where the initiator\n\t// completes the handshake by reading the responder's stage-2 message.\n\t// noise returns (cs1, cs2) where cs1 is the initiator->responder cipher.\n\t// For 3-message patterns where a responder finishes by reading the final\n\t// message, this ordering would be wrong; revisit when XX/pqIX lands.\n\tmsg, eKey, dKey, err := m.hs.ReadMessage(nil, packet[header.Len:])\n\tif err != nil {\n\t\t// Noise ReadMessage failed. The noise library checkpoints and rolls back\n\t\t// on failure, so the Machine is still alive. The caller can retry with\n\t\t// a different packet.\n\t\treturn nil, nil, fmt.Errorf(\"noise ReadMessage: %w\", err)\n\t}\n\n\t// From here on, noise state has advanced. Any error is fatal.\n\tflags := m.peerMsgFlags()\n\n\tif err := m.processPayload(msg, flags); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\t// If ReadMessage derived keys, the handshake is complete. Noise should\n\t// always produce both keys together; asymmetry is a protocol invariant\n\t// violation.\n\tif eKey != nil || dKey != nil {\n\t\tif eKey == nil || dKey == nil {\n\t\t\tm.failed = true\n\t\t\treturn nil, nil, ErrAsymmetricCipherKeys\n\t\t}\n\t\tif err := m.requireComplete(); err != nil {","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/handshake/machine.go#L215-L251","documentation":"ProcessPacket wraps an error from m.hs.ReadMessage (the Noise library) as 'noise ReadMessage: %w'. A Noise handshake message failed to decrypt/authenticate. The Noise library checkpoints state and rolls back on failure, so the Machine stays alive and the caller may retry with a different packet.","triggerScenarios":"ProcessPacket receives a packet whose handshake message body does not decrypt under the current handshake state — reordered/duplicated packets during the handshake, a packet from a different peer session, or a truncated/corrupted UDP datagram, while m.msgs[m.i] expects a message at that index.","commonSituations":"UDP packet loss causing out-of-order delivery during handshake, NAT rebinding mixing sessions, MTU fragmentation corrupting large handshake messages, MITM or wrong lighthouse routing delivering another peer's packet.","solutions":["Retransmit/resend the handshake stage — the machine rolled back and can accept a fresh packet","Check for UDP packet loss/fragmentation between peers (MTU tuning, keep handshake packets small)","Clear stale hostmap entries for the peer so a fresh handshake starts","Verify no middlebox is rewriting/duplicating UDP traffic on the Nebula port"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// optionally validate packet size and header before processing\nif len(packet) <= header.Len {\n\treturn fmt.Errorf(\"packet too short for handshake header\")\n}","typeGuard":null,"tryCatchPattern":"msg, _, _, err := machine.ProcessPacket(pkt)\nif err != nil && strings.Contains(err.Error(), \"noise ReadMessage:\") {\n\t// state rolled back; safe to retry with a fresh/retransmitted packet\n\treturn retryHandshakeStage(pkt)\n}","preventionTips":["Ensure handshake retransmission timers are enabled (handshakes are retried automatically)","Keep handshake packets under MTU to avoid fragmentation loss","Avoid multiple Nebula processes sharing one UDP port with different sessions","Monitor UDP loss/reordering between sites; tune network or use a reliable underlay for lossy links"],"tags":["handshake","noise","decryption","udp"],"backgroundTag":"noise-decrypt-failed","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"}