XTLS/Xray-core · warning

insufficient length of packet.

Error message

insufficient length of packet.

What it means

Thrown by DecodeUDPPacket when decoding a SOCKS5 UDP datagram whose total length is less than 5 bytes. A valid SOCKS5 UDP header needs at minimum the 2 reserved bytes, 1 fragment byte, plus at least 2 bytes for address/port encoding. The library rejects anything shorter because the header cannot possibly be parsed.

Source

Thrown at proxy/socks/protocol.go:346

	return buf.WriteAllBytes(writer, buffer.Bytes(), nil)
}

func writeSocks4Response(writer io.Writer, errCode byte, address net.Address, port net.Port) error {
	buffer := buf.StackNew()
	defer buffer.Release()

	common.Must(buffer.WriteByte(0x00))
	common.Must(buffer.WriteByte(errCode))
	portBytes := buffer.Extend(2)
	binary.BigEndian.PutUint16(portBytes, port.Value())
	common.Must2(buffer.Write(address.IP()))
	return buf.WriteAllBytes(writer, buffer.Bytes(), nil)
}

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

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. If you control the client, verify it prepends the 10+ byte SOCKS5 UDP header (RSV/FRAG + ATYP + addr + port) before payload.
  2. Inspect the raw datagram length before decoding and ignore sub-5-byte datagrams as noise.
  3. Check for path truncation (VPN/QUIC/UDP-relay MTU issues) if legitimate traffic keeps failing.
  4. Grep logs for the source address of these packets — most are scanners, safe to drop.

Example fix

// before
header, err := DecodeUDPPacket(packet)
if err != nil { return err }

// after
if packet.Len() < 5 {
	// ignore tiny/empty datagrams (scanners, keepalives)
	packet.Release()
	continue
}
header, err := DecodeUDPPacket(packet)
Defensive patterns

Strategy: validation

Validate before calling

if packet.Len() < 5 {
	// too small to contain RSV+FRAG+ATYP+port; drop it
	packet.Release()
	continue
}

Try / catch

if _, err := socks.DecodeUDPPacket(packet); err != nil {
	if strings.HasPrefix(err.Error(), "insufficient length") {
		continue // noise, not fatal
	}
	return err
}

Prevention

When it happens

Trigger: Calling DecodeUDPPacket on a *buf.Buffer whose Len() < 5: e.g. an empty UDP datagram, a 1-4 byte keepalive/health-check probe, or a truncated packet delivered by handleUDPPayload on the SOCKS inbound UDP path.

Common situations: Port scanners or monitoring systems sending tiny UDP probes to the SOCKS UDP port; a client with a broken/fragmented UDP encoder; MTU-truncation on the path between client and inbound.

Related errors


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