{"record":{"id":"ae88ad39d8de8a27","repo":"slackhq/nebula","slug":"erripv4packettooshort","errorCode":"ErrIPv4PacketTooShort","errorMessage":"ipv4 packet is too short","messagePattern":"ipv4 packet is too short","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"outside.go","lineNumber":314,"sourceCode":"\t\t\treturn\n\t\t}\n\n\t\thostinfo.logger(f.l).Info(\"Host roamed to new udp ip/port.\",\n\t\t\t\"udpAddr\", curRemote,\n\t\t\t\"newAddr\", via.UdpAddr,\n\t\t)\n\t\thostinfo.lastRoam = time.Now()\n\t\thostinfo.lastRoamRemote = curRemote\n\t\thostinfo.SetRemote(via.UdpAddr)\n\t}\n\n}\n\nvar (\n\tErrPacketTooShort          = errors.New(\"packet is too short\")\n\tErrUnknownIPVersion        = errors.New(\"packet is an unknown ip version\")\n\tErrIPv4InvalidHeaderLength = errors.New(\"invalid ipv4 header length\")\n\tErrIPv4PacketTooShort      = errors.New(\"ipv4 packet is too short\")\n\tErrIPv6PacketTooShort      = errors.New(\"ipv6 packet is too short\")\n)\n\n// newPacket validates and parses the interesting bits for the firewall out of the ip and sub protocol headers\nfunc newPacket(data []byte, incoming bool, fp *firewall.ParsedPacket) error {\n\t// fp is reused across packets; reset the parse byproducts so an early-error return cannot\n\t// leak the previous packet's offsets.\n\tfp.IPHdrLen = 0\n\tfp.FragAny = false\n\tif len(data) < 1 {\n\t\treturn ErrPacketTooShort\n\t}\n\n\tversion := int((data[0] >> 4) & 0x0f)\n\tswitch version {\n\tcase ipv4.Version:\n\t\treturn parseV4(data, incoming, fp)\n\tcase ipv6.Version:","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/outside.go#L296-L332","documentation":"parseV4 requires at least a full IPv4 header (ipv4.HeaderLen = 20 bytes) worth of data before parsing. Packets smaller than that cannot possibly contain a valid IPv4 header, so they are rejected early with ErrIPv4PacketTooShort.","triggerScenarios":"newPacket receives data of length < 20 bytes with version nibble 4 (outside.go:412); Test_newPacket feeds a single byte 0x40 to trigger it.","commonSituations":"Runt packets from MTU misconfiguration, truncation by proxies/NATs, scanner noise on the nebula UDP port, corrupted datagrams from the underlay.","solutions":["Confirm the underlay MTU is at least the nebula overhead + minimum IP header size.","Identify and block sources of runt/garbage packets hitting the port.","Enable packet logging to capture offending packets for diagnosis."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if len(data) < 20 {\n    return errors.New(\"too short for an ipv4 header\")\n}","typeGuard":null,"tryCatchPattern":"if errors.Is(err, outside.ErrIPv4PacketTooShort) {\n    // drop runt packet; investigate source if persistent\n}","preventionTips":["Enforce correct MTU on the underlay path.","Block known scanner sources on the nebula port.","Track runt-packet rates as an underlay quality metric."],"tags":["ipv4","packet-parsing","short-packet"],"backgroundTag":"packet-too-short","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}