slackhq/nebula · error
csum offsets out of range: start=%d offset=%d len=%d
Error message
csum offsets out of range: start=%d offset=%d len=%d
What it means
Range check in FinishChecksum: CsumStart+CsumOffset+2 exceeds the packet length, so the 16-bit checksum field the kernel asked us to finalize lies outside the buffer. The message reports start, offset, and length; it means the virtio header offsets and the actual segment size disagree.
Source
Thrown at overlay/tio/virtio/segment_linux.go:419
}
binary.BigEndian.PutUint16(seg[csumStart+udpChecksumOff:csumStart+udpChecksumOff+2], csum)
if err := yield(seg); err != nil {
return err
}
}
return nil
}
// FinishChecksum computes the L4 checksum for a non-GSO packet that the kernel handed us with NEEDS_CSUM set.
// CsumStart / CsumOffset point at the 16-bit checksum field.
// We zero it, fold a full sum from the partial one that the kernel provided, and store the result.
func FinishChecksum(seg []byte, hdr Hdr) error {
cs := int(hdr.CsumStart)
co := int(hdr.CsumOffset)
if cs+co+2 > len(seg) {
return fmt.Errorf("csum offsets out of range: start=%d offset=%d len=%d", cs, co, len(seg))
}
// The kernel stores a partial pseudo-header sum at [cs+co:]; sum over the
// L4 region starting at cs, folding the prior partial in as the seed.
partial := binary.BigEndian.Uint16(seg[cs+co : cs+co+2])
seg[cs+co] = 0
seg[cs+co+1] = 0
csum := ^checksum.Checksum(seg[cs:], partial)
// RFC 768: UDP transmits a computed zero as all ones, since all-zero is the reserved "no checksum" value.
if co == udpChecksumOff && csum == 0 {
csum = 0xffff
}
binary.BigEndian.PutUint16(seg[cs+co:cs+co+2], csum)
return nil
}
// foldComplement folds a 32-bit one's-complement partial sum to 16 bits and
// complements it, yielding the on-wire Internet checksum value.
func foldComplement(sum uint32) uint16 {View on GitHub (pinned to dd8f660c0a)
Solutions
- Drop the malformed segment
- Check vnet header size negotiation (VIRTIO_NET_HDR size vs TUNSETOFFLOAD)
- Log hdr and seg length to find which peer/kernel produces the bad offsets
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at overlay/tio/virtio/segment_linux.go:419 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/679d2382240438eb.
Report an issue: GitHub.