XTLS/Xray-core · error · errors.Error

cannot dial remote address

Error message

cannot dial remote address 

What it means

Thrown in app/observatory/observer.go:148 when tagged.Dialer — Xray's outbound dispatch dialer — fails to establish the connection from the probed outbound to the probe destination. This is the direct 'this outbound could not connect' signal for the observatory, with the failing destination embedded in the message.

Source

Thrown at app/observatory/observer.go:148

func (o *Observer) probe(outbound string) ProbeResult {
	errorCollectorForRequest := newErrorCollector()

	httpTransport := http.Transport{
		Proxy: func(*http.Request) (*url.URL, error) {
			return nil, nil
		},
		DialContext: func(ctx context.Context, network string, addr string) (net.Conn, error) {
			var connection net.Conn
			taskErr := task.Run(ctx, func() error {
				// MUST use Xray's built in context system
				dest, err := v2net.ParseDestination(network + ":" + addr)
				if err != nil {
					return errors.New("cannot understand address").Base(err)
				}
				trackedCtx := session.TrackedConnectionError(o.ctx, errorCollectorForRequest)
				conn, err := tagged.Dialer(trackedCtx, o.dispatcher, dest, outbound)
				if err != nil {
					return errors.New("cannot dial remote address ", dest).Base(err)
				}
				connection = conn
				return nil
			})
			if taskErr != nil {
				return nil, errors.New("cannot finish connection").Base(taskErr)
			}
			return connection, nil
		},
		TLSHandshakeTimeout: time.Second * 5,
	}
	httpClient := &http.Client{
		Transport: &httpTransport,
		CheckRedirect: func(req *http.Request, via []*http.Request) error {
			return http.ErrUseLastResponse
		},
		Jar:     nil,
		Timeout: time.Second * 5,

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Verify the outbound server is up and credentials (id/password) match on both ends.
  2. Check streamSettings (TLS/REALITY settings, SNI, port) of the failing outbound.
  3. Ensure routing rules do not intercept the probe traffic (destination is the probe URL) and loop it incorrectly.
  4. Look at the chained Base error for the precise protocol-level failure.
Defensive patterns

Strategy: fallback

Try / catch

// consumers of ProbeResult: treat dial failure as node-down and switch traffic, don't crash
if !result.Alive {
    router.MarkOutboundDead(tag)
    log.WithError(chainRoot(result.LastErrorReason)).Warn("outbound probe failed")
}

Prevention

When it happens

Trigger: The selected outbound handler's proxy handshake or underlying transport fails while the probe connection is dispatched: server down, refused TCP connection, wrong credentials, proxy protocol error, or routing rule sending the probe to a black hole.

Common situations: The single most common observatory error in production: an outbound VMess/Trojan/Shadowsocks server is offline or its credentials changed, and the observer immediately reports the outbound dead with this as the underlying cause.

Related errors


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