2dust/v2rayN · error · NotSupportedException

SOCKS5 UDP fragmentation is not supported

Error message

SOCKS5 UDP fragmentation is not supported

What it means

Thrown when the FRAG byte (3rd byte of a SOCKS5 UDP header) is non-zero. RFC 1928 allows UDP fragmentation via the FRAG field, but this implementation only supports unfragmented datagrams (FRAG == 0x00). Any proxy that actually fragments its UDP relay replies will trip this.

Source

Thrown at v2rayN/ServiceLib.UdpTest/Socks5UdpChannel.cs:116

    }

    private static (Socks5RemoteEndpoint Remote, byte[] Data) ParseSocks5UdpPacket(byte[] packet)
    {
        if (packet.Length < 10) // Minimum length: RSV(2) + FRAG(1) + ATYP(1) + IPv4(4) + Port(2) = 10
        {
            throw new ArgumentException("Invalid SOCKS5 UDP packet: too short");
        }

        var offset = 0;

        // RSV (2 bytes) - Reserved field, skip
        offset += 2;

        // FRAG (1 byte) - Fragment number, currently only support 0 (no fragmentation)
        var frag = packet[offset++];
        if (frag != 0x00)
        {
            throw new NotSupportedException("SOCKS5 UDP fragmentation is not supported");
        }

        // ATYP (1 byte) - Address type
        var addressType = packet[offset++];

        string host;
        int addressLength;
        bool isDomain;

        switch (addressType)
        {
            case Socks5AddressData.AddrTypeIPv4:
                if (packet.Length < offset + 4)
                {
                    throw new ArgumentException("Invalid SOCKS5 UDP packet: IPv4 address incomplete");
                }

                var ipv4Bytes = new byte[4];

View on GitHub (pinned to e01717d832)

Solutions

  1. Reduce the response size so it fits in a single unfragmented datagram (use a smaller test query or a tester with a compact reply such as DNS A-record queries).
  2. Switch to a SOCKS5 proxy that does not fragment UDP, or raise the path MTU between client and proxy.
  3. Catch NotSupportedException around ReceiveAsync and report 'fragmentation unsupported' to the user rather than crashing.
  4. If fragmentation support is required, extend ParseSocks5UdpPacket to reassemble FRAG-ordered chunks before parsing.

Example fix

// before - any non-zero FRAG aborts the whole test
var frag = packet[offset++];
if (frag != 0x00)
{
    throw new NotSupportedException("SOCKS5 UDP fragmentation is not supported");
}

// after - surface as a recoverable per-attempt failure
try
{
    var (_, receiveResult) = await channel.ReceiveAsync(cancellationToken);
}
catch (NotSupportedException ex) when (ex.Message.Contains("fragmentation"))
{
    // retry with a smaller request or mark attempt failed
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check the FRAG byte before full parse
static bool IsUnfragmented(byte[] p) => p != null && p.Length >= 3 && p[2] == 0x00;

Type guard

static bool IsUnfragmentedSocks5Udp(byte[] packet) => packet != null && packet.Length >= 3 && packet[2] == 0x00;

Try / catch

try
{
    var (remote, data) = ParseSocks5UdpPacket(packet);
}
catch (NotSupportedException ex) when (ex.Message.Contains("fragmentation"))
{
    // proxy fragmented a large reply; reduce request size or pick a smaller tester
}

Prevention

When it happens

Trigger: ReceiveAsync parses a relay packet whose FRAG byte != 0x00. This happens when the SOCKS5 server fragments a large response across multiple UDP datagrams using the RFC 1928 fragmentation mechanism.

Common situations: Testing a target whose response exceeds the path MTU (e.g. a large DNS response >512 bytes, large STUN/ McBe payload) over a proxy that enables UDP fragmentation; proxy implementation that always sets a non-zero FRAG.

Related errors


AI-assisted analysis of 2dust/v2rayN@e01717d832 (2026-08-13). Data as JSON: /api/errors/f2c5f6a2e28da973. Report an issue: GitHub.