OpenNHP/opennhp · error
missing remote peer public key
Error message
missing remote peer public key
What it means
Device.validateMsgData always requires md.PeerPk (the remote peer's static public key) when PrevParserData is nil, regardless of device type. The peer key is needed to verify and encrypt messages for the counterparty; sending without it is impossible.
Solutions
- Look up the peer's public key from the device's peer table and set md.PeerPk before sending
- Redeploy synchronized peer tables after key rotation (see AGENTS.md key rotation notes)
- In tests, generate peer keys via keygen helpers instead of leaving PeerPk nil
- Confirm the config file lists the remote peer so the device can resolve its public key
Example fix
// before
md := &MsgData{Msg: msg, RemoteAddr: addr}
// after
peer, ok := dev.GetPeer(remotePubKeyBase64)
if !ok { return errors.New("unknown peer") }
md := &MsgData{Msg: msg, RemoteAddr: addr, PeerPk: peer.PublicKey} Defensive patterns
Strategy: validation
Validate before calling
if md.PeerPk == nil {
return errors.New("PeerPk required")
} Type guard
func hasPeerKey(md *nhpcore.MsgData) bool { return md.PeerPk != nil } Try / catch
if err := dev.MsgToPacket(md); err != nil && strings.Contains(err.Error(), "missing remote peer public key") {
return fmt.Errorf("peer %s not in peer table", peerId)
} Prevention
- Resolve peer keys from the device peer table before every send
- After key rotation, redeploy all peer tables in lockstep
- Add startup checks that all configured peers have public keys
When it happens
Trigger: Any MsgToPacket or server-side message assembly where MsgData.PeerPk is nil and PrevParserData is nil — even when ConnData or RemoteAddr is correctly set.
Common situations: Loading peer keys from a stale or empty server.toml peer table; key rotation (e.g. after generate-nhp-keys.sh --regenerate) leaving code with the wrong key id; tests building MsgData without a peer key.
Related errors
- invalid input key
- invalid input key
- failed to create device
- decode private key
- extractInitiatorStaticPubKey: init hash
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/9df98f8e2b3f5f80.
Report an issue: GitHub.
Appendix: source
Thrown at nhp/core/initiator.go:50
ClPkc bool // 0: non-CL-PKC extented, 1: CL-PKC extended
ExternalPacket *Packet
ExternalCookie *[CookieSize]byte
Message []byte
PeerPk []byte
EncryptedPktCh chan *MsgAssemblerData
ResponseMsgCh chan *PacketParserData
}
func (d *Device) validateMsgData(md *MsgData) (err error) {
if md.PrevParserData == nil {
if d.deviceType == NHP_SERVER && md.ConnData == nil {
err = fmt.Errorf("missing connection data for server")
} else if d.deviceType != NHP_SERVER && md.RemoteAddr == nil {
err = fmt.Errorf("missing remote address")
}
if md.PeerPk == nil {
err = fmt.Errorf("missing remote peer public key")
}
}
return err
}
type MsgAssemblerData struct {
device *Device
BasePacket *Packet
connData *ConnectionData
ciphers *CipherSuite
deviceEcdh Ecdh
ephermeralEcdh Ecdh
header Header
hmacHash hash.Hash
chainHash hash.Hash
bodyAead cipher.AEADView on GitHub (pinned to 6e04ca5ff0)