XTLS/Xray-core · warning

failed to find an available destination

Error message

failed to find an available destination

What it means

Thrown when the trojan client's retry loop (ExponentialBackoff 5 attempts starting at 100ms) fails on every dial to server.Destination. It wraps the last dial error and is marked AtWarning: the tunnel cannot be established at all, and after ~3s of retries the request fails.

Source

Thrown at proxy/trojan/client.go:72

	ob.Name = "trojan"
	ob.CanSpliceCopy = 3
	destination := ob.Target
	network := destination.Network

	server := c.server
	var conn stat.Connection

	err := retry.ExponentialBackoff(5, 100).On(func() error {
		rawConn, err := dialer.Dial(ctx, server.Destination)
		if err != nil {
			return err
		}

		conn = rawConn
		return nil
	})
	if err != nil {
		return errors.New("failed to find an available destination").AtWarning().Base(err)
	}
	errors.LogInfo(ctx, "tunneling request to ", destination, " via ", server.Destination.NetAddr())

	defer conn.Close()

	user := server.User
	account, ok := user.Account.(*MemoryAccount)
	if !ok {
		return errors.New("user account is not valid")
	}

	var newCtx context.Context
	var newCancel context.CancelFunc
	if session.TimeoutOnlyFromContext(ctx) {
		newCtx, newCancel = context.WithCancel(context.Background())
	}

	sessionPolicy := c.policyManager.ForLevel(user.Level)

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Check the Base error: dial tcp ... i/o timeout vs TLS errors point to network vs certificate problems.
  2. Verify the trojan server is up and the port open (nc -vz host port, openssl s_client -connect host:port).
  3. Confirm outbound address/port/password and streamSettings (TLS serverName) match the server exactly.
  4. If the IP is blocked, switch to a new server address or use a CDN-fronted transport.
  5. Fix DNS: ensure the server domain resolves (try domainStrategy UseIPv4 or a reliable DNS server in config).
Defensive patterns

Strategy: retry

Validate before calling

// preflight reachability before committing the tunnel
if err := probeTCP(server.Destination.NetAddr(), 3*time.Second); err != nil {
	return errors.New("trojan server unreachable: ").Base(err)
}

Try / catch

if err := client.Process(ctx, link, dialer); err != nil {
	if strings.Contains(err.Error(), "failed to find an available destination") {
		backoff.Retry(...) // or switch to the backup server in the config
	}
}

Prevention

When it happens

Trigger: dialer.Dial(ctx, server.Destination) failing 5 consecutive times: connection refused/timeout, TLS handshake failure to the trojan server, DNS resolution failure of the server address, or the server port blocked.

Common situations: Trojan server down or moved; wrong address/port in outbound; SNI/serverName mismatch causing TLS failure; GFW/firewall blocking the server IP; DNS for the server domain poisoned or expired.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/5dd28f26418e3104. Report an issue: GitHub.