{"record":{"id":"29a1d23f987a9c9e","repo":"XTLS/Xray-core","slug":"failed-to-find-an-available-destination","errorCode":null,"errorMessage":"failed to find an available destination","messagePattern":"failed to find an available destination","errorType":"exception","errorClass":"errors.Error","httpStatus":null,"severity":"error","filePath":"proxy/http/client.go","lineNumber":116,"sourceCode":"\theader, err := fillRequestHeader(ctx, c.header)\n\tif err != nil {\n\t\treturn errors.New(\"failed to fill out header\").Base(err)\n\t}\n\n\tif err := retry.ExponentialBackoff(5, 100).On(func() error {\n\t\tnetConn, err := setUpHTTPTunnel(ctx, dest, targetAddr, user, dialer, header, firstPayload)\n\t\tif netConn != nil {\n\t\t\tif _, ok := netConn.(*http2Conn); !ok {\n\t\t\t\tif _, err := netConn.Write(firstPayload); err != nil {\n\t\t\t\t\tnetConn.Close()\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t\tconn = stat.Connection(netConn)\n\t\t}\n\t\treturn err\n\t}); err != nil {\n\t\treturn errors.New(\"failed to find an available destination\").Base(err)\n\t}\n\n\tdefer func() {\n\t\tif err := conn.Close(); err != nil {\n\t\t\terrors.LogInfoInner(ctx, err, \"failed to closed connection\")\n\t\t}\n\t}()\n\n\tp := c.policyManager.ForLevel(0)\n\tif user != nil {\n\t\tp = c.policyManager.ForLevel(user.Level)\n\t}\n\n\tvar newCtx context.Context\n\tvar newCancel context.CancelFunc\n\tif session.TimeoutOnlyFromContext(ctx) {\n\t\tnewCtx, newCancel = context.WithCancel(context.Background())\n\t}","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/proxy/http/client.go#L98-L134","documentation":"setUpHTTPTunnel was retried with ExponentialBackoff(5, 100ms) and every attempt failed — dialing the proxy, TLS/ALPN negotiation, the CONNECT round-trip, or writing the first payload. After exhausting retries the last error is wrapped as \"failed to find an available destination\".","triggerScenarios":"HTTP proxy server down/unreachable, CONNECT rejected with non-200 (auth failure, forbidden target), TLS handshake failure when TLS is in play, or first-payload write after non-h2 CONNECT failing repeatedly. The 5-attempt backoff amplifies transient errors into a single final failure.","commonSituations":"Wrong credentials in settings.servers[].users, proxy requiring allowlisting the Xray host's IP, proxy that blocks CONNECT to non-443 ports, cached h2 conn going stale (CanTakeNewRequest false) forcing fresh failures.","solutions":["Unwrap the Base error to see the last attempt's actual failure (dial vs non-200 vs TLS)","Test the proxy by hand: `curl -x http://user:pass@proxy:3128 https://target -v`","Fix credentials/allowlist/port policy on the proxy side","If non-200, check the proxy's response code — 407 means auth, 403 means policy"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"```go\n// one-shot probe before trusting the outbound\nif err := probeHTTPTunnel(ctx, proxyDest, user, dialer); err != nil {\n    // surface proxy misconfig early instead of 5 blind retries\n}\n```","typeGuard":null,"tryCatchPattern":"```go\nif err := c.Process(ctx, link, dialer); err != nil {\n    if strings.Contains(err.Error(), \"failed to find an available destination\") {\n        base := errors.Unwrap(err) // last retry's cause: dial / non-200 / TLS\n        // only retry on transient dial errors; fix auth/ACL otherwise\n    }\n}\n```","preventionTips":["curl-test proxies before adding them to config","Keep credentials in sync with the proxy","Watch for stale cached h2 connections after proxy restarts"],"tags":["http-outbound","connect","retry","proxy","xray"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}