{"record":{"id":"278f74c83f674947","repo":"XTLS/Xray-core","slug":"failed-to-read-udp-header","errorCode":null,"errorMessage":"failed to read UDP header","messagePattern":"failed to read UDP header","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/socks/protocol.go","lineNumber":362,"sourceCode":"func DecodeUDPPacket(packet *buf.Buffer) (*protocol.RequestHeader, error) {\n\tif packet.Len() < 5 {\n\t\treturn nil, errors.New(\"insufficient length of packet.\")\n\t}\n\trequest := &protocol.RequestHeader{\n\t\tVersion: socks5Version,\n\t\tCommand: protocol.RequestCommandUDP,\n\t}\n\n\t// packet[0] and packet[1] are reserved\n\tif packet.Byte(2) != 0 /* fragments */ {\n\t\treturn nil, errors.New(\"discarding fragmented payload.\")\n\t}\n\n\tpacket.Advance(3)\n\n\taddr, port, err := addrParser.ReadAddressPort(nil, packet)\n\tif err != nil {\n\t\treturn nil, errors.New(\"failed to read UDP header\").Base(err)\n\t}\n\trequest.Address = addr\n\trequest.Port = port\n\treturn request, nil\n}\n\nfunc EncodeUDPPacket(request *protocol.RequestHeader, data []byte) (*buf.Buffer, error) {\n\tb := buf.New()\n\tcommon.Must2(b.Write([]byte{0, 0, 0 /* Fragment */}))\n\tif err := addrParser.WriteAddressPort(b, request.Address, request.Port); err != nil {\n\t\tb.Release()\n\t\treturn nil, err\n\t}\n\t// if data is too large, return an empty buffer (drop too big data)\n\tif b.Available() < int32(len(data)) {\n\t\tb.Clear()\n\t\treturn b, nil\n\t}","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/proxy/socks/protocol.go#L344-L380","documentation":"Thrown when the address/port portion of a SOCKS5 UDP header cannot be parsed by addrParser.ReadAddressPort after the 3-byte RSV/FRAG prefix was consumed. It wraps the underlying parse error, so the real cause (bad address type byte, truncated address, invalid domain length) is in the Base error chain.","triggerScenarios":"DecodeUDPPacket on a datagram >= 5 bytes where bytes 3..n do not form a valid ATYP + address + port tuple: unknown address type (not 0x01/0x03/0x04), domain length byte larger than remaining data, or port bytes missing.","commonSituations":"Corrupted datagrams from a malfunctioning client; packets from a non-SOCKS UDP service accidentally arriving on the SOCKS UDP port (wrong port in client config); version skew where a client encodes a non-standard address type.","solutions":["Log the wrapped base error and hex-dump the first bytes of the datagram to see which field is malformed.","Confirm the client is sending to the SOCKS5 UDP relay port returned by UDP ASSOCIATE, not to a random inbound port.","Verify client and server both implement standard ATYP values 0x01 (IPv4), 0x03 (domain), 0x04 (IPv6).","If datagrams arrive corrupt, check for a mangling middlebox (NAT, DPI) on the UDP path."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if _, err := socks.DecodeUDPPacket(packet); err != nil {\n\tlog.Debug(\"udp header parse failed: \", err) // err chain carries base cause\n\tcontinue // drop malformed datagram, keep serving others\n}","preventionTips":["Hex-dump failing datagrams once during debugging to find the bad field.","Ensure clients send only ATYP 0x01/0x03/0x04.","Confirm the client targets the UDP ASSOCIATE-returned port, not the TCP port."],"tags":["socks","socks5","udp","address-parsing","protocol"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}