{"record":{"id":"11b5c0c027c8d70a","repo":"XTLS/Xray-core","slug":"invalid-url","errorCode":null,"errorMessage":"invalid URL: ","messagePattern":"invalid URL: ","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"main/confloader/external/external.go","lineNumber":59,"sourceCode":"\treturn\n}\n\n// FetchHTTPContent issues an HTTP GET against either a regular HTTP(S) URL\n// or a Unix socket HTTP endpoint.\n//\n//\thttp(s)://host/api          regular HTTP(S)\n//\t/path/to/socket.sock[:/api] filesystem socket\n//\t@abstract[:/api]            abstract socket (Linux/Android)\n//\t@@padded[:/api]             padded abstract socket (HAProxy compat)\n//\n// When the \":/\" separator is omitted on a socket target, the request is\n// made to \"/\".\nfunc FetchHTTPContent(target string) ([]byte, error) {\n\thttpURL, socketPath := utils.SplitHTTPUnixURL(target)\n\n\tparsedTarget, err := url.Parse(httpURL)\n\tif err != nil {\n\t\treturn nil, errors.New(\"invalid URL: \", target).Base(err)\n\t}\n\n\tclient := &http.Client{\n\t\tTimeout: 30 * time.Second,\n\t}\n\n\tif socketPath != \"\" {\n\t\tdialAddr := utils.ResolveSocketPath(socketPath)\n\t\tclient.Transport = &http.Transport{\n\t\t\tDialContext: func(ctx context.Context, _, _ string) (net.Conn, error) {\n\t\t\t\tvar d net.Dialer\n\t\t\t\treturn d.DialContext(ctx, \"unix\", dialAddr)\n\t\t\t},\n\t\t}\n\t}\n\n\tresp, err := client.Do(&http.Request{\n\t\tMethod: \"GET\",","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/main/confloader/external/external.go#L41-L77","documentation":"Thrown by FetchHTTPContent after utils.SplitHTTPUnixURL splits the target into an HTTP URL and an optional socket path. The remaining HTTP part is passed to url.Parse, which rejects strings containing control characters or otherwise malformed URL syntax. This is the entry point for Xray's remote config fetching, supporting plain http(s) plus Unix/abstract-socket targets.","triggerScenarios":"Calling confloader.LoadConfig with a target like \"http(s)://host/api\", \"/path/to/socket.sock:/api\", \"@abstract:/api\" or \"@@padded:/api\" where the URL portion contains control characters (e.g. raw newline/tab), an unsupported scheme remnant, or other input url.Parse refuses.","commonSituations":"Typos in the -config flag (missing scheme, stray whitespace or CR from copy-pasting a URL, unescaped spaces), or a Windows-style path accidentally passed as an http URL; also malformed socket-target syntax that SplitHTTPUnixURL does not normalize.","solutions":["Inspect the exact target string passed on the command line or in code; strip leading/trailing whitespace, newlines and carriage returns","Ensure the URL has a valid scheme: http:// or https:// for network, or /path, @name, @@name forms for sockets","URL-encode any spaces or special characters in the path/query portion of the target","If the target is a local file, remove any http-like prefix and pass the filesystem path instead"],"exampleFix":"// before\ncontent, err := external.FetchHTTPContent(\"http://example.com/conf x.json\\n\")\n\n// after\ntarget := strings.TrimSpace(\"http://example.com/conf%20x.json\")\ncontent, err := external.FetchHTTPContent(target)","handlingStrategy":"validation","validationCode":"import (\"net/url\"; \"strings\")\n\nfunc validFetchTarget(target string) bool {\n    t := strings.TrimSpace(target)\n    if t == \"\" { return false }\n    httpPart, _ := utils.SplitHTTPUnixURL(t) // or replicate the split\n    _, err := url.Parse(httpPart)\n    return err == nil\n}","typeGuard":null,"tryCatchPattern":"if content, err := external.FetchHTTPContent(t); err != nil {\n    if strings.HasPrefix(err.Error(), \"invalid URL\") { fixTarget(t); continue }\n    return err\n}","preventionTips":["Trim whitespace/newlines from any URL pulled from env vars or flags","Centralize config-URL construction in one helper that validates with url.Parse","Prefer static, well-formed URLs; avoid assembling them from untrusted fragments"],"tags":["go","xray","config","url-parsing","http"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}