BeyondDimension/SteamTools · error · AggregateException
Could not find any IP that can be successfully connected.
Error message
Could not find any IP that can be successfully connected.
What it means
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.
Source
Thrown at src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/Http/ReverseProxyHttpClientHandler.cs:288
try
{
using var timeoutTokenSource = new CancellationTokenSource(connectTimeout);
using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(timeoutTokenSource.Token, cancellationToken);
return await ConnectAsync(context, ipEndPoint, linkedTokenSource.Token);
}
catch (OperationCanceledException)
{
cancellationToken.ThrowIfCancellationRequested();
innerExceptions.Add(new TimeoutException(
$"HTTP connection to {ipEndPoint.Address} timed out."));
}
catch (Exception ex)
{
innerExceptions.Add(ex);
}
}
throw new AggregateException("Could not find any IP that can be successfully connected.", innerExceptions);
}
/// <summary>
/// 建立连接
/// </summary>
/// <param name="context"></param>
/// <param name="ipEndPoint"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
async ValueTask<Stream> ConnectAsync(SocketsHttpConnectionContext context, IPEndPoint ipEndPoint, CancellationToken cancellationToken)
{
var socket = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
await socket.ConnectAsync(ipEndPoint, cancellationToken);
var stream = new NetworkStream(socket, ownsSocket: true);
var requestContext = context.InitialRequestMessage.GetRequestContext();
if (requestContext.IsHttps == false)
{View on GitHub (pinned to c16ffa08e0)
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.
Example fix
// before: caller lets AggregateException propagate opaquely
try { await httpClient.SendAsync(req, ct); }
catch (AggregateException) { throw; }
// after: unwrap and report the dominant failure type
try { await httpClient.SendAsync(req, ct); }
catch (AggregateException ex)
{
if (ex.InnerExceptions.All(e => e is TimeoutException))
throw new TimeoutException("All upstream IPs timed out.", ex);
throw;
} Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight: resolve the host and confirm at least one endpoint is TCP-reachable.
async Task<bool> AnyEndpointReachableAsync(string host, int port, CancellationToken ct)
{
try
{
var addrs = await Dns.GetHostAddressesAsync(host, ct);
foreach (var a in addrs)
{
using var s = new TcpClient();
using var cts = CancellationTokenSource.CreateLinkedTokenSource(ct);
cts.CancelAfter(3000);
try { await s.ConnectAsync(a, port, cts.Token); return true; }
catch { /* try next */ }
}
}
catch { }
return false;
} Try / catch
try { await httpClient.SendAsync(request, ct); }
catch (AggregateException ex) when (ex.Message.Contains("Could not find any IP"))
{
var allTimeouts = ex.InnerExceptions.All(e => e is TimeoutException);
if (attempt < maxAttempts && allTimeouts) { await Task.Delay(backoff, ct); goto retry; }
Log.Error($"All IPs failed: {string.Join("; ", ex.InnerExceptions.Select(e => e.Message))}");
throw;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unable to connect to {host}
- Unable to connect to {endPoint.Host}:{endPoint.Port}.
- TCP port {httpProxyPort} is already occupied by other proces
- Failed to get available ports. There are no available ports.
- Failed to obtain badge information status code: {status}
AI-assisted analysis of BeyondDimension/SteamTools@c16ffa08e0 (2026-08-13).
Data as JSON: /api/errors/726121f4c3a962ae.
Report an issue: GitHub.