OpenNHP/opennhp · warning
packet total size is incorrect
Error message
packet total size is incorrect
What it means
Device.RecvPrecheck compares the buffer's total length with headerSize plus the payload size declared in the packet header. A mismatch means the datagram is truncated, padded, or otherwise malformed, so parsing would read out of bounds; the packet is rejected before decryption.
Solutions
- Size the UDP receive buffer to the maximum NHP packet size so nothing is truncated
- Check that relays forward the datagram unmodified (same length)
- Log header size vs actual length to identify systematic truncation
- If sender-side, ensure SetHeaderTypeAndSize is called after the full payload is written
Example fix
// before
buf := make([]byte, 256) // too small for full packet
n, _ := conn.Read(buf)
// after
buf := make([]byte, nhpcore.MaxPacketSize)
n, _ := conn.Read(buf)
pkt := &nhpcore.Packet{Content: buf[:n]} Defensive patterns
Strategy: validation
Validate before calling
if len(pkt.Content) < nhpcore.HeaderSize {
return errors.New("truncated packet")
}
t, s := pkt.HeaderTypeAndSize()
if len(pkt.Content) != nhpcore.HeaderSize+s {
return errors.New("length mismatch")
} Type guard
func fullPacket(pkt *nhpcore.Packet) bool {
t, s := pkt.HeaderTypeAndSize()
return len(pkt.Content) == nhpcore.HeaderSize+s && t >= 0
} Try / catch
if _, _, err := dev.RecvPrecheck(pkt); err != nil && strings.Contains(err.Error(), "total size is incorrect") {
log.Warnf("malformed datagram (%d bytes) dropped", len(pkt.Content))
return
} Prevention
- Allocate receive buffers large enough for max-size NHP packets
- Ensure relays forward datagrams byte-for-byte
- Check MTU/fragmentation on lossy links
When it happens
Trigger: recvPacketRoutine, HandleRelayForward, or PacketToMsg reads a datagram where len(pkt.Content) != headerSize + s (declared header payload size), e.g. UDP truncation or a corrupted size field.
Common situations: Using a receive buffer smaller than the datagram so UDP truncates it; fragmentation issues on constrained networks; hand-crafted or fuzzed packets; relay forwarding with modified buffers.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- inner packet too large
- missing remote address
- unknown remote provider
- unknown remote provider
- unsupported key type, expect RSA
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/141590f1148888d0.
Report an issue: GitHub.
Appendix: source
Thrown at nhp/core/packet.go:258
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}
}
func (d *Device) ReleasePoolPacket(pkt *Packet) {
if pkt != nil && pkt.Buf != nil && pkt.PoolAllocated {
d.pool.Put(pkt.Buf)
pkt.Buf = nil
pkt.Content = nil
}
}
View on GitHub (pinned to 6e04ca5ff0)