XTLS/Xray-core · error

failed to read UDP header

Error message

failed to read UDP header

What it means

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.

Source

Thrown at proxy/socks/protocol.go:362

func DecodeUDPPacket(packet *buf.Buffer) (*protocol.RequestHeader, error) {
	if packet.Len() < 5 {
		return nil, errors.New("insufficient length of packet.")
	}
	request := &protocol.RequestHeader{
		Version: socks5Version,
		Command: protocol.RequestCommandUDP,
	}

	// packet[0] and packet[1] are reserved
	if packet.Byte(2) != 0 /* fragments */ {
		return nil, errors.New("discarding fragmented payload.")
	}

	packet.Advance(3)

	addr, port, err := addrParser.ReadAddressPort(nil, packet)
	if err != nil {
		return nil, errors.New("failed to read UDP header").Base(err)
	}
	request.Address = addr
	request.Port = port
	return request, nil
}

func EncodeUDPPacket(request *protocol.RequestHeader, data []byte) (*buf.Buffer, error) {
	b := buf.New()
	common.Must2(b.Write([]byte{0, 0, 0 /* Fragment */}))
	if err := addrParser.WriteAddressPort(b, request.Address, request.Port); err != nil {
		b.Release()
		return nil, err
	}
	// if data is too large, return an empty buffer (drop too big data)
	if b.Available() < int32(len(data)) {
		b.Clear()
		return b, nil
	}

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Log the wrapped base error and hex-dump the first bytes of the datagram to see which field is malformed.
  2. Confirm the client is sending to the SOCKS5 UDP relay port returned by UDP ASSOCIATE, not to a random inbound port.
  3. Verify client and server both implement standard ATYP values 0x01 (IPv4), 0x03 (domain), 0x04 (IPv6).
  4. If datagrams arrive corrupt, check for a mangling middlebox (NAT, DPI) on the UDP path.
Defensive patterns

Strategy: try-catch

Try / catch

if _, err := socks.DecodeUDPPacket(packet); err != nil {
	log.Debug("udp header parse failed: ", err) // err chain carries base cause
	continue // drop malformed datagram, keep serving others
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/278f74c83f674947. Report an issue: GitHub.