slackhq/nebula · error

end of checksum offset (%d) exceeds packet length (%d)

Error message

end of checksum offset (%d) exceeds packet length (%d)

What it means

Packet-validation error in CorrectHdrLen (virtio receive path): the two-byte checksum field at CsumStart+CsumOffset would end past the end of the packet. The virtioNetHdr offsets from the kernel point outside the actual buffer, so the checksum cannot be fixed up; both the computed end offset and packet length are reported.

Source

Thrown at overlay/tio/virtio/segment_linux.go:153

		}

		tcpHLen := uint16(pkt[hdr.CsumStart+tcpDataOffOff] >> 4 * 4)
		if tcpHLen < tcpHeaderMinLen || tcpHLen > tcpHeaderMaxLen {
			return fmt.Errorf("tcp header len is invalid: %d", tcpHLen)
		}
		hdr.HdrLen = hdr.CsumStart + tcpHLen
	}

	if len(pkt) < int(hdr.HdrLen) {
		return fmt.Errorf("length of packet (%d) < virtioNetHdr.HdrLen (%d)", len(pkt), hdr.HdrLen)
	}

	if hdr.HdrLen < hdr.CsumStart {
		return fmt.Errorf("virtioNetHdr.HdrLen (%d) < virtioNetHdr.CsumStart (%d)", hdr.HdrLen, hdr.CsumStart)
	}
	cSumAt := int(hdr.CsumStart + hdr.CsumOffset)
	if cSumAt+1 >= len(pkt) {
		return fmt.Errorf("end of checksum offset (%d) exceeds packet length (%d)", cSumAt+1, len(pkt))
	}
	return nil
}

// segCount returns how many segments a payload of payLen bytes splits into at gsoSize,
// with a floor of one so a header-only superpacket still yields a single segment.
func segCount(payLen, gsoSize int) int {
	n := (payLen + gsoSize - 1) / gsoSize
	if n == 0 {
		return 1
	}
	return n
}

// basePseudoSum folds the part of the L4 pseudo-header sum that is identical
// for every segment: the source and destination addresses plus the protocol
// number. The per-segment L4 length is added by the caller inside the loop.
func basePseudoSum(pkt []byte, isV4 bool, proto uint32) uint32 {

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Drop the malformed packet and let upper layers retransmit
  2. Treat as a kernel/virtio negotiation mismatch: check TUNSETOFFLOAD vs negotiated vnet header size
  3. Capture the packet and hdr fields to diagnose the off-by-N in CsumStart/CsumOffset
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at overlay/tio/virtio/segment_linux.go:153 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/a92ba92f3e60e133. Report an issue: GitHub.