slackhq/nebula · warning
errPacketTooShort
errPacketTooShort
Error message
packet too short
What it means
errPacketTooShort is returned by CheckValid in the virtio TSO segmentation code when a packet is shorter than the minimum IPv4 header length, or is IPv6 but shorter than the fixed IPv6 header (40 bytes), so header fields cannot be read safely during segmentation. It protects the TSO segmenter from out-of-bounds reads.
Source
Thrown at overlay/tio/virtio/segment_linux.go:65
ipv6AddrsEnd = 40 // end of dst address (ipv6SrcOff + 2*16)
)
// Byte offsets inside a TCP header (relative to its start, i.e. csumStart).
const (
tcpSeqOff = 4
tcpDataOffOff = 12 // upper nibble is header len in 32-bit words
tcpFlagsOff = 13
tcpChecksumOff = 16
)
// UDP header is fixed at 8 bytes: {sport, dport, length, checksum}.
const (
udpHeaderLen = 8
udpLengthOff = 4
udpChecksumOff = 6
)
var errPacketTooShort = errors.New("packet too short")
// tcpFinPshMask is cleared on every segment except the last of a TSO burst.
const tcpFinPshMask = 0x09 // FIN(0x01) | PSH(0x08)
// tcpCwrFlag is cleared on every segment except the first.
// Per RFC 3168 §6.1.2 the CWR bit signals a one-shot transition (the sender just halved its window)
// and must appear on the first segment of a TSO burst only.
const tcpCwrFlag = 0x80
// CheckValid rejects packets whose virtio_net_hdr/IP combination would
// cause a downstream miscompute. The TUN should never emit RSC_INFO and
// the GSO type must agree with the IP version nibble.
func CheckValid(pkt []byte, hdr Hdr) error {
if hdr.Flags&unix.VIRTIO_NET_HDR_F_RSC_INFO != 0 {
return fmt.Errorf("virtio RSC_INFO flag not supported on TUN reads")
}
if len(pkt) < ipv4HeaderMinLen {
return errPacketTooShortView on GitHub (pinned to dd8f660c0a)
Solutions
- Drop the offending packet and increment a malformed-packet counter rather than attempting segmentation.
- Validate packet length before passing it to the TSO path; only segment packets with complete IP headers.
- Check virtio guest driver version/mergeable Rx buffer negotiation — mismatches can produce short buffers.
- Audit vring buffer sizes vs MTU to ensure a full max-size frame always fits in one descriptor chain.
- If it comes from a hypervisor/guest update, roll back or fix the emitting driver.
Example fix
// before: assume all ring packets are segmentable
for _, pkt := range pkts {
if err := seg.CheckValid(pkt); err != nil {
return err
}
}
// after: skip and count short packets
for _, pkt := range pkts {
if err := seg.CheckValid(pkt); err != nil {
if errors.Is(err, errPacketTooShort) {
stats.Malformed++
continue
}
return err
}
} Defensive patterns
Strategy: validation
Validate before calling
func canSegment(pkt []byte) bool {
if len(pkt) < ipv4HeaderMinLen {
return false
}
if v := pkt[0] >> 4; v == 6 {
return len(pkt) >= ipv6FixedLen
} else if v != 4 {
return false
}
return true
}
if !canSegment(pkt) {
stats.Malformed++
return // skip CheckValid/segmentation
} Try / catch
if err := seg.CheckValid(pkt); err != nil {
if errors.Is(err, errPacketTooShort) {
stats.Malformed++
return nil // drop, keep processing ring
}
return err
} Prevention
- Length-check packets against ipv4HeaderMinLen/ipv6FixedLen before the TSO path.
- Verify virtio mergeable-buffer and GSO negotiation with the guest driver.
- Size vring descriptor chains to fit full max-MTU frames.
- Drop-and-count malformed frames instead of failing the whole Rx loop.
When it happens
Trigger: CheckValid(pkt) is called with len(pkt) < ipv4HeaderMinLen, or with IP version 6 (pkt[0]>>4 == 6) and len(pkt) < ipv6FixedLen. This happens when the host hands the virtio ring a malformed/truncated packet marked for GSO/TSO segmentation.
Common situations: Guest driver bugs emitting short descriptors; corrupted virtio ring entries; packets truncated by MTU/mergeable-buffer misconfiguration; fuzzing or hostile guests sending malformed frames to the vhost device.
Related errors
- packet is too short
- ErrIPv6CouldNotFindPayload
- ErrBadDetailsVpnAddr
- ErrPacketTooShort
- ErrUnknownIPVersion
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/a1504ae9f97585b9.
Report an issue: GitHub.