XTLS/Xray-core · error
cannot dial remote address
Error message
cannot dial remote address
What it means
The tagged.Dialer callback failed to establish the connection to the parsed destination through the routing dispatcher using the configured outbound tag. The message appends the destination and chains the real dial failure (connect refused, DNS failure, outbound missing, etc.) via .Base(err).
Source
Thrown at app/geodata/download.go:79
httpClient: newClient(ctx, dispatcher, outbound, false),
httpsClient: newClient(ctx, dispatcher, outbound, true),
}
}
func newClient(baseCtx context.Context, dispatcher routing.Dispatcher, outbound string, isHTTPS bool) *http.Client {
dial := func(ctx context.Context, network, address string) (net.Conn, error) {
var conn net.Conn
err := task.Run(ctx, func() error {
if tagged.Dialer == nil {
return errors.New("tagged dialer is not initialized")
}
dest, err := net.ParseDestination(network + ":" + address)
if err != nil {
return errors.New("cannot understand address").Base(err)
}
c, err := tagged.Dialer(baseCtx, dispatcher, dest, outbound)
if err != nil {
return errors.New("cannot dial remote address ", dest).Base(err)
}
conn = c
return nil
})
if err != nil {
return nil, errors.New("cannot finish connection").Base(err)
}
return &idleConn{
Conn: conn,
}, nil
}
if isHTTPS {
return &http.Client{
Transport: &http2.Transport{
DialTLSContext: func(ctx context.Context, network string, address string, cfg *tls.Config) (net.Conn, error) {
conn, err := dial(ctx, network, address)
if err != nil {
return nil, errView on GitHub (pinned to 7d214f8b09)
Solutions
- Read the chained Base error — it names the real cause (unknown outbound tag vs connect refused vs DNS)
- Make sure the outbound tag configured for geodata download exists among the configured outbounds
- Test the same proxy with curl through Xray to confirm the outbound can reach the geodata mirror
- Temporarily remove the geodata outbound tag so the downloader uses the default dispatcher path
Example fix
// xray config: ensure the outbound referenced by geodata exists
// before (broken):
"geodata": { "outboundTag": "warp" } // no outbound named warp
// after:
"outbounds": [ { "tag": "warp", "protocol": "vless", ... } ],
"geodata": { "outboundTag": "warp" } Defensive patterns
Strategy: retry
Validate before calling
// Verify the outbound tag exists in config before enabling geodata updates:
func outboundExists(cfg *core.Config, tag string) bool {
for _, o := range cfg.Outbound {
if o.Tag == tag { return true }
}
return false
} Try / catch
err = d.download(assets)
if err != nil {
if e, ok := err.(*errors.Error); ok && strings.HasPrefix(e.Message(), "cannot dial remote address") {
// outbound-level failure: fall back to default dispatcher or next mirror
}
} Prevention
- Keep the geodata outboundTag in sync with the outbounds list during config edits
- Health-check the designated proxy before scheduled geodata updates
- Have a fallback asset URL on a different host
When it happens
Trigger: tagged.Dialer(baseCtx, dispatcher, dest, outbound) returning an error: the outbound named by the geodata config's Outbound tag does not exist, the proxy is down, or the dispatcher rejected the routing.
Common situations: geodata.outboundTag points to a proxy tag that was removed from the outbounds list; the selected proxy server is unreachable; routing rules route the geodata traffic to a blackhole; DNS resolution of the mirror host fails through the proxy.
Related errors
- connection idle timeout
- cannot understand address
- cannot finish connection
- redirected to non-https URL:
- stopped after 10 redirects
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/7882e4276db76f7a.
Report an issue: GitHub.