{"record":{"id":"dc733fe414deb2af","repo":"BeyondDimension/SteamTools","slug":"unable-to-connect-to-endpoint-host-endpoint-por","errorCode":null,"errorMessage":"Unable to connect to {endPoint.Host}:{endPoint.Port}.","messagePattern":"Unable to connect to (.+?):(.+?)\\.","errorType":"exception","errorClass":"AggregateException","httpStatus":null,"severity":"error","filePath":"src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/HttpServer/TcpReverseProxyHandler.cs","lineNumber":62,"sourceCode":"        var innerExceptions = new List<Exception>();\n        await foreach (var address in domainResolver.ResolveAsync(endPoint, cancellationToken))\n        {\n            var socket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);\n            try\n            {\n                using var timeoutTokenSource = new CancellationTokenSource(connectTimeout);\n                using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutTokenSource.Token);\n                await socket.ConnectAsync(address, endPoint.Port, linkedTokenSource.Token);\n                return new NetworkStream(socket, ownsSocket: false);\n            }\n            catch (Exception ex)\n            {\n                socket.Dispose();\n                cancellationToken.ThrowIfCancellationRequested();\n                innerExceptions.Add(ex);\n            }\n        }\n        throw new AggregateException(\n            $\"Unable to connect to {endPoint.Host}:{endPoint.Port}.\", innerExceptions);\n    }\n}\n#endif","sourceCodeStart":44,"sourceCodeEnd":66,"githubUrl":"https://github.com/BeyondDimension/SteamTools/blob/c16ffa08e03b192d23ada290c4969e77f9201f3d/src/BD.WTTS.Client.Plugins.Accelerator.ReverseProxy/Services.Implementation/HttpServer/TcpReverseProxyHandler.cs#L44-L66","documentation":"Thrown by the TCP reverse-proxy handler when socket.ConnectAsync failed for every address tried for an endpoint. As with the other connect paths, each failure is appended to innerExceptions (with cancellation re-checked) and the final AggregateException names the target host:port.","triggerScenarios":"Handling a TCP reverse-proxy request where connecting to endPoint.Host:endPoint.Port fails or times out for all resolved addresses within connectTimeout.","commonSituations":"Destination game/service host is down; firewall blocks the destination port; DNS returns private/unreachable IPs; the proxied TCP service moved or changed port; network path broken (VPN/route misconfiguration).","solutions":["Examine innerExceptions for the failure mode (refused vs timeout vs unreachable).","Verify endPoint.Host:endPoint.Port is reachable directly from the host (telnet/Test-NetConnection).","Check the reverse-proxy route/mapping table maps to the correct destination host and port.","Confirm DNS/routing for the destination and that no firewall/ISP blocks the port."],"exampleFix":"// before\nthrow new AggregateException(\n    $\"Unable to connect to {endPoint.Host}:{endPoint.Port}.\", innerExceptions);\n\n// after: retry once with a fresh socket on transient failures before aggregating\nvar transient = innerExceptions.Any(e => e is SocketException or TimeoutException);\nif (transient && attempt < maxAttempts) goto retry;\nthrow new AggregateException(\n    $\"Unable to connect to {endPoint.Host}:{endPoint.Port} after {attempt} attempts.\",\n    innerExceptions);","handlingStrategy":"retry","validationCode":"// Verify the destination endpoint before proxying.\nasync Task<bool> IsEndpointReachableAsync(EndPoint ep, CancellationToken ct)\n{\n    using var s = new TcpClient();\n    using var cts = CancellationTokenSource.CreateLinkedTokenSource(ct);\n    cts.CancelAfter(connectTimeout);\n    try { await s.ConnectAsync(ep, cts.Token); return true; }\n    catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try { await ProxyTcpAsync(endPoint, ct); }\ncatch (AggregateException ex) when (ex.Message.Contains(\"Unable to connect to\"))\n{\n    if (attempt < maxAttempts && ex.InnerExceptions.Any(e => e is SocketException or TimeoutException))\n    { await Task.Delay(backoff, ct); goto retry; }\n    Log.Warning($\"TCP upstream {endPoint.Host}:{endPoint.Port} unreachable: \"\n        + string.Join(\"; \", ex.InnerExceptions.Select(e => e.Message)));\n    throw;\n}","preventionTips":["Keep the route table mapping destinations to known-good host:port pairs.","Use a short connectTimeout and a bounded retry policy for transient failures.","Health-check TCP destinations in the background and rotate away unhealthy ones.","Distinguish timeout vs refused in logs to pinpoint firewall vs offline services."],"tags":["network","tcp","proxy","connection"],"backgroundTag":null,"analyzedSha":"c16ffa08e03b192d23ada290c4969e77f9201f3d","analyzedAt":"2026-08-13T11:52:20.410Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}