{"record":{"id":"70b52cdd3b44a48f","repo":"2dust/v2rayN","slug":"failed-to-build-udp-request-packet","errorCode":null,"errorMessage":"Failed to build UDP request packet.","messagePattern":"Failed to build UDP request packet\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"v2rayN/ServiceLib.UdpTest/UdpTestService.cs","lineNumber":98,"sourceCode":"            var portStr = targetServerHost.Substring(lastColonIndex + 1);\n            if (ushort.TryParse(portStr, out var port))\n            {\n                return (host, port);\n            }\n        }\n\n        // No port specified, use default\n        return (targetServerHost, _udpTest.GetDefaultTargetPort());\n    }\n\n    public async Task<TimeSpan> SendUdpRequestAsync(string targetServerHost, int socks5Port, TimeSpan operationTimeout)\n    {\n        using var cts = new CancellationTokenSource(operationTimeout);\n        var cancellationToken = cts.Token;\n        var udpRequestPacket = _udpTest.BuildUdpRequestPacket();\n        if (udpRequestPacket == null || udpRequestPacket.Length == 0)\n        {\n            throw new InvalidOperationException(\"Failed to build UDP request packet.\");\n        }\n        using var channel = new Socks5UdpChannel(\"127.0.0.1\", socks5Port);\n        if (!await channel.EstablishUdpAssociationAsync(cancellationToken).ConfigureAwait(false))\n        {\n            throw new Exception(\"Failed to establish UDP association with SOCKS5 proxy.\");\n        }\n\n        var (targetHost, targetPort) = ParseHostAndPort(targetServerHost);\n\n        byte[] udpReceiveResult = null;\n\n        // Get minimum round trip time from two attempts\n        var roundTripTime = TimeSpan.MaxValue;\n\n        for (var attempt = 0; attempt < 2; attempt++)\n        {\n            try\n            {","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/2dust/v2rayN/blob/e01717d8326a4f5060b335523590c5fda943fe03/v2rayN/ServiceLib.UdpTest/UdpTestService.cs#L80-L116","documentation":"Thrown by SendUdpRequestAsync when the injected IUdpTest.BuildUdpRequestPacket() returns null or an empty array. The service cannot send an empty datagram, so it aborts before opening the channel. In the shipped testers (Dns/Ntp/Stun/McBe) BuildUdpRequestPacket always returns a non-empty clone, so a hit indicates a misconfigured/null tester.","triggerScenarios":"SendUdpRequestAsync calls _udpTest.BuildUdpRequestPacket(); the result is null or Length == 0, raising InvalidOperationException before any socket work.","commonSituations":"A custom IUdpTest implementation returns null from BuildUdpRequestPacket; the tester was not initialized or its static query packet is empty; dependency injection wired a null/default tester.","solutions":["Ensure the IUdpTest implementation returns a non-empty, well-formed request packet from BuildUdpRequestPacket (the built-in testers clone a static byte array).","Verify the correct tester instance is injected into UdpTestService (DnsService, NtpService, StunService, or McBeService).","Unit-test the tester's BuildUdpRequestPacket to assert a non-null, non-empty result.","If extending IUdpTest, initialize the request packet in a static field or constructor so it is never null."],"exampleFix":"// before - custom tester may return null/empty\npublic byte[] BuildUdpRequestPacket() => _packet; // _packet could be null\n\n// after - guarantee a non-empty packet\nprivate static readonly byte[] Packet = /* ... */;\npublic byte[] BuildUdpRequestPacket() => (byte[])Packet.Clone();","handlingStrategy":"validation","validationCode":"// Validate the tester packet before sending\nvar packet = _udpTest.BuildUdpRequestPacket();\nif (packet == null || packet.Length == 0)\n    throw new InvalidOperationException($\"Tester {_udpTest.GetType().Name} produced an empty request packet.\");","typeGuard":"static bool IsValidUdpRequestPacket(byte[] packet) => packet != null && packet.Length > 0;","tryCatchPattern":"try\n{\n    await SendUdpRequestAsync(host, port, timeout);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"build UDP request\"))\n{\n    // the injected IUdpTest is misconfigured; check DI registration / tester init\n}","preventionTips":["Ensure custom IUdpTest implementations return a non-empty clone of a static request packet.","Register the correct tester instance in DI.","Unit-test BuildUdpRequestPacket for non-null/non-empty output."],"tags":["udp-test","validation","configuration"],"backgroundTag":null,"analyzedSha":"e01717d8326a4f5060b335523590c5fda943fe03","analyzedAt":"2026-08-13T10:10:23.416Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}