OpenNHP/opennhp · warning

keepalive packet size is incorrect

Error message

keepalive packet size is incorrect

What it means

Device.RecvPrecheck validates an incoming packet's header before decryption. NHP keepalive packets (NHP_KPL) must carry zero payload; any nonzero size is rejected with this error. It guards against keepalives carrying unexpected data.

Solutions

  1. Fix the sender so keepalive packets are sent with an empty payload
  2. Upgrade/align both endpoints to the same NHP protocol version
  3. If corruption is suspected, check network path/MTU and UDP checksums
  4. For testing, build keepalives via the library's packet constructor, not hand-crafted bytes

Example fix

// before
pkt := dev.AllocatePoolPacket()
pkt.SetHeaderTypeAndSize(nhpcore.NHP_KPL, len(payload)) // payload on keepalive
// after
pkt := dev.AllocatePoolPacket()
pkt.SetHeaderTypeAndSize(nhpcore.NHP_KPL, 0) // keepalives are empty
Defensive patterns

Strategy: validation

Validate before calling

t, s := pkt.HeaderTypeAndSize()
if t == nhpcore.NHP_KPL && s != 0 {
    return errors.New("keepalive with payload")
}

Type guard

func isBareKeepalive(pkt *nhpcore.Packet) bool {
    t, s := pkt.HeaderTypeAndSize()
    return t == nhpcore.NHP_KPL && s == 0
}

Try / catch

t, s, err := dev.RecvPrecheck(pkt)
if err != nil && strings.Contains(err.Error(), "keepalive packet size") {
    log.Warnf("bad keepalive from %v", sender)
    continue
}

Prevention

When it happens

Trigger: recvPacketRoutine, HandleRelayForward, or PacketToMsg receives a packet whose header type is NHP_KPL but whose declared payload size (s) is nonzero.

Common situations: Interoperating with a peer implementation that appends data to keepalives; version mismatch where keepalive format changed; packet corruption flipping size bytes on the wire.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07). Data as JSON: /api/errors/b22218f77874ae6f. Report an issue: GitHub.

Appendix: source

Thrown at nhp/core/packet.go:249

		switch t {
		case NHP_DRG, NHP_DAG, NHP_DAK, NHP_DBA, NHP_DWR:
			return true
		}
	}
	log.Info("Device type: %d, recv header type %d not allowed", d.deviceType, t)
	return false
}

func (d *Device) RecvPrecheck(pkt *Packet) (int, int, error) {
	headerSize := pkt.Header().Size()

	// check type and payload size
	t, s := pkt.HeaderTypeAndSize()
	if t == NHP_KPL {
		if s == 0 {
			return t, s, nil
		} else {
			return t, s, fmt.Errorf("keepalive packet size is incorrect")
		}
	}
	if !d.CheckRecvHeaderType(t) {
		return t, s, fmt.Errorf("packet header type does not match device")
	}

	totalLen := len(pkt.Content)
	if totalLen != headerSize+s {
		return t, s, fmt.Errorf("packet total size is incorrect")
	}

	return t, s, nil
}

func (d *Device) AllocatePoolPacket() *Packet {
	buf := d.pool.Get()
	return &Packet{Buf: buf, Content: buf[:], PoolAllocated: true}
}

View on GitHub (pinned to 6e04ca5ff0)