2dust/v2rayN · error · Exception

Failed to establish UDP association with SOCKS5 proxy.

Error message

Failed to establish UDP association with SOCKS5 proxy.

What it means

Thrown when EstablishUdpAssociationAsync returns false, meaning the TCP control handshake to the SOCKS5 proxy failed at some stage: TCP connect, method negotiation, UDP ASSOCIATE command reply, or parsing the relay bind address. It is a generic catch-all because the handshake returns false for several distinct failures rather than throwing.

Source

Thrown at v2rayN/ServiceLib.UdpTest/UdpTestService.cs:103

        }

        // No port specified, use default
        return (targetServerHost, _udpTest.GetDefaultTargetPort());
    }

    public async Task<TimeSpan> SendUdpRequestAsync(string targetServerHost, int socks5Port, TimeSpan operationTimeout)
    {
        using var cts = new CancellationTokenSource(operationTimeout);
        var cancellationToken = cts.Token;
        var udpRequestPacket = _udpTest.BuildUdpRequestPacket();
        if (udpRequestPacket == null || udpRequestPacket.Length == 0)
        {
            throw new InvalidOperationException("Failed to build UDP request packet.");
        }
        using var channel = new Socks5UdpChannel("127.0.0.1", socks5Port);
        if (!await channel.EstablishUdpAssociationAsync(cancellationToken).ConfigureAwait(false))
        {
            throw new Exception("Failed to establish UDP association with SOCKS5 proxy.");
        }

        var (targetHost, targetPort) = ParseHostAndPort(targetServerHost);

        byte[] udpReceiveResult = null;

        // Get minimum round trip time from two attempts
        var roundTripTime = TimeSpan.MaxValue;

        for (var attempt = 0; attempt < 2; attempt++)
        {
            try
            {
                var stopwatch = new Stopwatch();
                stopwatch.Start();
                await channel.SendAsync(targetHost, targetPort, udpRequestPacket).ConfigureAwait(false);
                var (_, receiveResult) = await channel.ReceiveAsync(cancellationToken).ConfigureAwait(false);
                stopwatch.Stop();

View on GitHub (pinned to e01717d832)

Solutions

  1. Confirm a SOCKS5 inbound listener is up on socks5Port (e.g. netstat/ss, or a SOCKS5 TCP curl through it).
  2. Ensure the proxy offers 'no-auth' (method 0x00); this channel sends only [0x05,0x01,0x00] and rejects any other method.
  3. Verify socks5Port is the SOCKS5 inbound port, not an HTTP/mixed inbound.
  4. Retry after the proxy has fully started, or increase the start-up wait before invoking SendUdpRequestAsync.
  5. If the proxy only supports username/password auth, extend the handshake to offer method 0x02.

Example fix

// before - single attempt, opaque failure
if (!await channel.EstablishUdpAssociationAsync(ct))
{
    throw new Exception("Failed to establish UDP association with SOCKS5 proxy.");
}

// after - retry once and distinguish failure stages
var ok = false;
for (var i = 0; i < 2 && !ok; i++)
{
    ok = await channel.EstablishUdpAssociationAsync(ct);
}
if (!ok) throw new Exception("SOCKS5 UDP ASSOCIATE handshake failed; verify the proxy offers no-auth and supports UDP on port " + socks5Port);
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight: confirm a SOCKS5 listener is up before the UDP test
using var probe = new TcpClient();
try { await probe.ConnectAsync("127.0.0.1", socks5Port, ct); }
catch { throw new Exception($"No SOCKS5 listener on 127.0.0.1:{socks5Port}."); }

Type guard

static bool IsPlausibleSocks5Port(int port) => port > 0 && port < 65536;

Try / catch

try
{
    if (!await channel.EstablishUdpAssociationAsync(ct))
        throw new Exception("SOCKS5 UDP ASSOCIATE handshake failed; verify no-auth + UDP support on port " + socks5Port);
}
catch (SocketException ex)
{
    // proxy not reachable / refused; retry after proxy startup or report
}

Prevention

When it happens

Trigger: SendUdpRequestAsync opens a Socks5UdpChannel on 127.0.0.1:socks5Port and awaits EstablishUdpAssociationAsync; it returns false due to a SocketException on connect, a bad SOCKS5 version/no-auth reply (ver!=0x05 or method!=0x00), a non-success UDP ASSOCIATE reply (rep!=0x00), or an unparseable relay address.

Common situations: SOCKS5 proxy not running on the expected local port; proxy requires auth (no 'no-auth' method 0x00); proxy does not support UDP ASSOCIATE; wrong port passed (e.g. HTTP/SOCKS inbound port instead of SOCKS5 inbound); firewall/loopback binding issue; proxy crashed or still starting.

Related errors


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