{"record":{"id":"a604ba1c3efdb906","repo":"MHSanaei/3x-ui","slug":"unsupported-proxy-scheme-q","errorCode":null,"errorMessage":"unsupported proxy scheme %q","messagePattern":"unsupported proxy scheme %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/util/netproxy/netproxy.go","lineNumber":61,"sourceCode":"\t\tif parsed.User != nil {\n\t\t\tpassword, _ := parsed.User.Password()\n\t\t\tauth = &proxy.Auth{User: parsed.User.Username(), Password: password}\n\t\t}\n\t\tdialer, err := proxy.SOCKS5(\"tcp\", parsed.Host, auth, proxy.Direct)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"create socks5 dialer: %w\", err)\n\t\t}\n\t\tif contextDialer, ok := dialer.(proxy.ContextDialer); ok {\n\t\t\ttransport.DialContext = contextDialer.DialContext\n\t\t} else {\n\t\t\ttransport.DialContext = func(_ context.Context, network, addr string) (net.Conn, error) {\n\t\t\t\treturn dialer.Dial(network, addr)\n\t\t\t}\n\t\t}\n\tcase \"http\", \"https\":\n\t\ttransport.Proxy = http.ProxyURL(parsed)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported proxy scheme %q\", parsed.Scheme)\n\t}\n\n\treturn &http.Client{Timeout: timeout, Transport: transport}, nil\n}\n\nfunc baseTransport() *http.Transport {\n\tif base, ok := http.DefaultTransport.(*http.Transport); ok {\n\t\treturn base.Clone()\n\t}\n\treturn &http.Transport{}\n}\n","sourceCodeStart":43,"sourceCodeEnd":73,"githubUrl":"https://github.com/MHSanaei/3x-ui/blob/ad32144c42455696ea9f14e12168beac3e25f5d2/internal/util/netproxy/netproxy.go#L43-L73","documentation":"After a socks5/socks5h and http/https case, NewHTTPClient's switch rejects every other scheme with 'unsupported proxy scheme %q'. The accepted set is exactly socks5, socks5h, http, https (matched case-insensitively). This is a strict allowlist: socks4, socks4a, ssh, or scheme-relative '//host:port' all land here.","triggerScenarios":"Setting the proxy URL to socks4://..., ssh://..., or a value like '127.0.0.1:1080' with no scheme (url.Parse yields Scheme=\"\"), then calling NewHTTPClient.","commonSituations":"User pastes a SOCKS4 proxy from an old config; omits the scheme entirely assuming SOCKS default; typo 'socks5h :' with a space; uses 'https_proxy' style env values with unsupported schemes.","solutions":["Change the scheme to one of socks5, socks5h, http, or https.","If the scheme was omitted, prepend socks5:// (or http://) explicitly.","For SOCKS4 proxies, put a SOCKS5 front (e.g. gost) in front or switch the proxy software to SOCKS5 mode."],"exampleFix":"// before\nproxyURL := \"127.0.0.1:1080\" // no scheme -> unsupported proxy scheme \"\"\n\n// after\nproxyURL := \"socks5://127.0.0.1:1080\"","handlingStrategy":"validation","validationCode":"var allowedSchemes = map[string]bool{\"socks5\": true, \"socks5h\": true, \"http\": true, \"https\": true}\n\nfunc allowedProxyScheme(raw string) bool {\n\tu, err := url.Parse(strings.TrimSpace(raw))\n\tif err != nil { return false }\n\treturn u.Scheme != \"\" && allowedSchemes[strings.ToLower(u.Scheme)]\n}","typeGuard":"func allowedProxyScheme(raw string) bool {\n\tu, err := url.Parse(strings.TrimSpace(raw))\n\tif err != nil { return false }\n\treturn allowedSchemes[strings.ToLower(u.Scheme)]\n}","tryCatchPattern":null,"preventionTips":["Show the accepted scheme list in the settings UI help text.","Default scheme-less values to socks5:// on save.","Reject socks4 at configuration time with a clear message."],"tags":["proxy","http-client","configuration","validation"],"backgroundTag":null,"analyzedSha":"ad32144c42455696ea9f14e12168beac3e25f5d2","analyzedAt":"2026-08-15T11:13:23.905Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}