2dust/v2rayN · error · ArgumentException

Invalid SOCKS5 UDP packet: domain incomplete

Error message

Invalid SOCKS5 UDP packet: domain incomplete

What it means

Thrown when the declared domain length exceeds the remaining bytes in the packet. The length-prefix said N bytes of domain name, but fewer than N bytes are actually present.

Source

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

                }

                var ipv6Bytes = new byte[16];
                Array.Copy(packet, offset, ipv6Bytes, 0, 16);
                host = new IPAddress(ipv6Bytes).ToString();
                addressLength = 16;
                isDomain = false;
                break;

            case Socks5AddressData.AddrTypeDomain:
                if (packet.Length < offset + 1)
                {
                    throw new ArgumentException("Invalid SOCKS5 UDP packet: domain length missing");
                }

                var domainLength = packet[offset++];
                if (packet.Length < offset + domainLength)
                {
                    throw new ArgumentException("Invalid SOCKS5 UDP packet: domain incomplete");
                }

                host = Encoding.ASCII.GetString(packet, offset, domainLength);
                addressLength = domainLength;
                isDomain = true;
                break;

            default:
                throw new NotSupportedException($"Unsupported SOCKS5 address type: {addressType}");
        }

        offset += addressLength;

        // Port (2 bytes, big-endian)
        if (packet.Length < offset + 2)
        {
            throw new ArgumentException("Invalid SOCKS5 UDP packet: port incomplete");
        }

View on GitHub (pinned to e01717d832)

Solutions

  1. Catch ArgumentException per attempt and continue to the next retry.
  2. Confirm the proxy writes the correct 1-byte domain length matching the hostname it relays.
  3. Sanity-check domainLength (e.g. reject values > 253, the max DNS label/hostname length) before trusting it.
  4. Log domainLength vs. remaining-bytes to distinguish a wrong length from truncation.
Defensive patterns

Strategy: validation

Validate before calling

// Sanity-check the declared domain length before trusting it
static bool IsValidDomainSpan(byte[] p, int offset)
{
    if (p == null || offset + 1 > p.Length) return false;
    var len = p[offset];
    return len > 0 && len <= 253 && offset + 1 + len <= p.Length;
}

Type guard

static bool IsCompleteDomainPacket(byte[] packet, int offset) => packet != null && offset + 1 <= packet.Length && (offset + 1 + packet[offset]) <= packet.Length;

Try / catch

try
{
    var (remote, data) = ParseSocks5UdpPacket(packet);
}
catch (ArgumentException ex) when (ex.Message.Contains("domain incomplete"))
{
    // declared length exceeds remaining bytes; corrupt length or truncation
}

Prevention

When it happens

Trigger: ParseSocks5UdpPacket reads ATYP == AddrTypeDomain, reads domainLength, then packet.Length < offset + domainLength; i.e. the length byte promised more name bytes than the datagram contains.

Common situations: Corrupt length byte (e.g. a high value from bit noise); truncated datagram after the length byte; proxy that writes a wrong domain length; packet loss dropping the tail of the relay datagram.

Related errors


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