{"record":{"id":"726121f4c3a962ae","repo":"BeyondDimension/SteamTools","slug":"could-not-find-any-ip-that-can-be-successfully-con","errorCode":null,"errorMessage":"Could not find any IP that can be successfully connected.","messagePattern":"Could not find any IP that can be successfully connected\\.","errorType":"exception","errorClass":"AggregateException","httpStatus":null,"severity":"error","filePath":"src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/Http/ReverseProxyHttpClientHandler.cs","lineNumber":288,"sourceCode":"            try\n            {\n                using var timeoutTokenSource = new CancellationTokenSource(connectTimeout);\n                using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(timeoutTokenSource.Token, cancellationToken);\n                return await ConnectAsync(context, ipEndPoint, linkedTokenSource.Token);\n            }\n            catch (OperationCanceledException)\n            {\n                cancellationToken.ThrowIfCancellationRequested();\n                innerExceptions.Add(new TimeoutException(\n                    $\"HTTP connection to {ipEndPoint.Address} timed out.\"));\n            }\n            catch (Exception ex)\n            {\n                innerExceptions.Add(ex);\n            }\n        }\n\n        throw new AggregateException(\"Could not find any IP that can be successfully connected.\", innerExceptions);\n    }\n\n    /// <summary>\n    /// 建立连接\n    /// </summary>\n    /// <param name=\"context\"></param>\n    /// <param name=\"ipEndPoint\"></param>\n    /// <param name=\"cancellationToken\"></param>\n    /// <returns></returns>\n    async ValueTask<Stream> ConnectAsync(SocketsHttpConnectionContext context, IPEndPoint ipEndPoint, CancellationToken cancellationToken)\n    {\n        var socket = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);\n        await socket.ConnectAsync(ipEndPoint, cancellationToken);\n        var stream = new NetworkStream(socket, ownsSocket: true);\n\n        var requestContext = context.InitialRequestMessage.GetRequestContext();\n        if (requestContext.IsHttps == false)\n        {","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/BeyondDimension/SteamTools/blob/c16ffa08e03b192d23ada290c4969e77f9201f3d/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/Http/ReverseProxyHttpClientHandler.cs#L270-L306","documentation":"Thrown by the custom SocketsHttpHandler connect callback after every resolved IP for a host failed to establish a TCP connection. Each attempt's exception is captured into innerExceptions (timeouts become TimeoutException, others pass through) and rethrown as an AggregateException once all candidates are exhausted.","triggerScenarios":"The handler iterates the DNS-resolved endpoints for a target host; each ConnectAsync times out (converted to TimeoutException) or throws (refused, network unreachable, TLS reset). With zero successful connections, the AggregateException is thrown.","commonSituations":"Upstream/game server is down or blocked by region; DNS returns stale/unreachable IPs; firewall or ISP blocks the port; proxy routing sends traffic to a dead node; captive portal intercepting; IPv6 addresses returned but not routable.","solutions":["Inspect AggregateException.InnerExceptions to see whether failures are timeouts, refusals, or DNS — each points to a different cause.","Verify network connectivity and that the target host:port is reachable from the host (test with a raw TCP connect).","Check the accelerator/proxy route configuration and failover nodes; switch to a working node.","Confirm DNS is returning valid IPs (try alternative DNS) and that firewall/antivirus is not blocking the outbound port."],"exampleFix":"// before: caller lets AggregateException propagate opaquely\ntry { await httpClient.SendAsync(req, ct); }\ncatch (AggregateException) { throw; }\n\n// after: unwrap and report the dominant failure type\ntry { await httpClient.SendAsync(req, ct); }\ncatch (AggregateException ex)\n{\n    if (ex.InnerExceptions.All(e => e is TimeoutException))\n        throw new TimeoutException(\"All upstream IPs timed out.\", ex);\n    throw;\n}","handlingStrategy":"retry","validationCode":"// Pre-flight: resolve the host and confirm at least one endpoint is TCP-reachable.\nasync Task<bool> AnyEndpointReachableAsync(string host, int port, CancellationToken ct)\n{\n    try\n    {\n        var addrs = await Dns.GetHostAddressesAsync(host, ct);\n        foreach (var a in addrs)\n        {\n            using var s = new TcpClient();\n            using var cts = CancellationTokenSource.CreateLinkedTokenSource(ct);\n            cts.CancelAfter(3000);\n            try { await s.ConnectAsync(a, port, cts.Token); return true; }\n            catch { /* try next */ }\n        }\n    }\n    catch { }\n    return false;\n}","typeGuard":null,"tryCatchPattern":"try { await httpClient.SendAsync(request, ct); }\ncatch (AggregateException ex) when (ex.Message.Contains(\"Could not find any IP\"))\n{\n    var allTimeouts = ex.InnerExceptions.All(e => e is TimeoutException);\n    if (attempt < maxAttempts && allTimeouts) { await Task.Delay(backoff, ct); goto retry; }\n    Log.Error($\"All IPs failed: {string.Join(\"; \", ex.InnerExceptions.Select(e => e.Message))}\");\n    throw;\n}","preventionTips":["Pin or prefer known-good upstream IPs and order them by latency to reduce wasted attempts.","Tune connectTimeout to the network profile (shorter for failover, longer for high-latency links).","Implement per-endpoint circuit breakers so a dead node is skipped quickly on subsequent calls.","Log each IP attempt's outcome so failures are diagnosable without reproducing."],"tags":["network","http","proxy","connection"],"backgroundTag":null,"analyzedSha":"c16ffa08e03b192d23ada290c4969e77f9201f3d","analyzedAt":"2026-08-13T11:52:20.410Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}