slackhq/nebula · error

udp header len mismatch: %d

Error message

udp header len mismatch: %d

What it means

Packet-validation error in SegmentUDP (virtio GSO segmentation): the UDP header length field found in the packet does not equal the expected 8 bytes for some segment. The computed per-segment UDP length disagrees with the on-wire header, indicating a corrupted or non-GSO packet passed to the segmentation path.

Source

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

// into pkt at offset i*GSOSize and yielding pkt[i*GSOSize:i*GSOSize+segLen] to the caller.
// Per-segment patches are total_len + IPv4 csum (or IPv6 payload_len) plus the UDP length and checksum.
// pkt is consumed destructively.
func SegmentUDP(pkt []byte, hdrLenU, csumStartU, gsoSizeU uint16, yield func(seg []byte) error) error {
	if gsoSizeU == 0 {
		return fmt.Errorf("gso_size is zero")
	}
	if csumStartU == 0 {
		return fmt.Errorf("csum_start is zero")
	}

	isV4 := pkt[0]>>4 == 4
	headerLen := int(hdrLenU)
	csumStart := int(csumStartU)
	if headerLen > maxSegHdrLen {
		return fmt.Errorf("header len %d exceeds max %d", headerLen, maxSegHdrLen)
	}
	if headerLen-csumStart != udpHeaderLen {
		return fmt.Errorf("udp header len mismatch: %d", headerLen-csumStart)
	}

	payLen := len(pkt) - headerLen
	gsoSize := int(gsoSizeU)
	numSeg := segCount(payLen, gsoSize)

	baseProtoSum := basePseudoSum(pkt, isV4, unix.IPPROTO_UDP)

	var origIPID uint16
	var baseIPHdrSum uint32
	if isV4 {
		origIPID = binary.BigEndian.Uint16(pkt[ipv4IDOff : ipv4IDOff+2])
		var err error
		// Software UDP GSO bumps the ID per segment just like TSO
		// (inet_gso_segment's fixed-ID case is TCP-only), so it stays out of the base sum.
		baseIPHdrSum, err = baseIPv4HdrSum(pkt, csumStart)
		if err != nil {
			return err

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Drop the packet and rely on retransmission
  2. Verify the GSO metadata (hdrLen, csumStart, gsoSize) matches the actual packet layout
  3. Disable GSO offload for the tun device if the kernel/peer negotiation is unreliable
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at overlay/tio/virtio/segment_linux.go:336 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/eb31dd27dc5950cd. Report an issue: GitHub.