{"record":{"id":"9b308fd7365a345a","repo":"XTLS/Xray-core","slug":"cannot-finish-connection","errorCode":null,"errorMessage":"cannot finish connection","messagePattern":"cannot finish connection","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/geodata/download.go","lineNumber":85,"sourceCode":"\tdial := func(ctx context.Context, network, address string) (net.Conn, error) {\n\t\tvar conn net.Conn\n\t\terr := task.Run(ctx, func() error {\n\t\t\tif tagged.Dialer == nil {\n\t\t\t\treturn errors.New(\"tagged dialer is not initialized\")\n\t\t\t}\n\t\t\tdest, err := net.ParseDestination(network + \":\" + address)\n\t\t\tif err != nil {\n\t\t\t\treturn errors.New(\"cannot understand address\").Base(err)\n\t\t\t}\n\t\t\tc, err := tagged.Dialer(baseCtx, dispatcher, dest, outbound)\n\t\t\tif err != nil {\n\t\t\t\treturn errors.New(\"cannot dial remote address \", dest).Base(err)\n\t\t\t}\n\t\t\tconn = c\n\t\t\treturn nil\n\t\t})\n\t\tif err != nil {\n\t\t\treturn nil, errors.New(\"cannot finish connection\").Base(err)\n\t\t}\n\t\treturn &idleConn{\n\t\t\tConn: conn,\n\t\t}, nil\n\t}\n\tif isHTTPS {\n\t\treturn &http.Client{\n\t\t\tTransport: &http2.Transport{\n\t\t\t\tDialTLSContext: func(ctx context.Context, network string, address string, cfg *tls.Config) (net.Conn, error) {\n\t\t\t\t\tconn, err := dial(ctx, network, address)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t}\n\t\t\t\t\thost, _, _ := net.SplitHostPort(address)\n\t\t\t\t\ttlsConn := utls.UClient(conn, &utls.Config{ServerName: host}, utls.HelloChrome_Auto)\n\t\t\t\t\thandshakeCtx, cancel := context.WithTimeout(ctx, idleTimeout)\n\t\t\t\t\tdefer cancel()\n\t\t\t\t\tif err := tlsConn.HandshakeContext(handshakeCtx); err != nil {","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/app/geodata/download.go#L67-L103","documentation":"Generic wrapper returned by the geodata dialer when task.Run (which encapsulates ParseDestination + tagged.Dialer) exits with any error. It is the outermost frame of the dial path; the specific cause is always in the chained Base error ('cannot understand address' or 'cannot dial remote address ...').","triggerScenarios":"Any failure inside the dial closure passed to task.Run for a geodata HTTP(S) request — address parse failure or dial failure — resurfaces from http.Client as this wrapped error.","commonSituations":"Same situations as errors 22 and 23: bad asset URL, missing/unreachable outbound, or network failure; users see this message first in logs and must inspect the chained cause.","solutions":["Inspect err.(*errors.Error).Base()/unwrap chain — the real cause is 'cannot understand address' or 'cannot dial remote address'","Fix the underlying cause per that inner error (URL format or outbound reachability)","Retry after network conditions change if the base cause is a transient connect failure"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"resp, err := client.Get(assetURL)\nif err != nil {\n    var xe *errors.Error\n    if errors.As(err, &xe) && strings.Contains(xe.Message(), \"cannot finish connection\") {\n        cause := xe.Base() // 'cannot understand address' or 'cannot dial remote address'\n        log.Warn(\"geodata dial failed: \", cause)\n    }\n    return err\n}","preventionTips":["Always unwrap to the Base cause before acting on this wrapper error","Treat it as a routing layer symptom, not a root cause"],"tags":["network","geodata","error-wrapping","download"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}