{"record":{"id":"499a8c360d5518db","repo":"MHSanaei/3x-ui","slug":"create-socks5-dialer-w","errorCode":null,"errorMessage":"create socks5 dialer: %w","messagePattern":"create socks5 dialer: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/util/netproxy/netproxy.go","lineNumber":49,"sourceCode":"\t}\n\n\tparsed, err := url.Parse(proxyURL)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parse proxy url: %w\", err)\n\t}\n\n\ttransport := baseTransport()\n\n\tswitch strings.ToLower(parsed.Scheme) {\n\tcase \"socks5\", \"socks5h\":\n\t\tvar auth *proxy.Auth\n\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 {","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/MHSanaei/3x-ui/blob/ad32144c42455696ea9f14e12168beac3e25f5d2/internal/util/netproxy/netproxy.go#L31-L67","documentation":"When the proxy scheme is socks5/socks5h, NewHTTPClient builds a dialer with golang.org/x/net/proxy.SOCKS5; if that constructor fails the error is wrapped as 'create socks5 dialer: %w'. proxy.SOCKS5 itself almost never fails for a well-formed address — it fails when the 'tcp' network is unknown to the registered forward dialer or the proxy address is not host:port, so in practice this surfaces malformed host:port strings that still passed url.Parse.","triggerScenarios":"NewHTTPClient with scheme socks5/socks5h where parsed.Host lacks a port ('socks5://1.2.3.4' — Host='1.2.3.4', no :port) or is otherwise not resolvable as an address by proxy.SOCKS5's internal net.Dial registration.","commonSituations":"Proxy setting entered without a port; IPv6 address unbracketed so the colons confuse host:port splitting; hostname with underscores that url parsing tolerates.","solutions":["Include an explicit port: socks5://127.0.0.1:1080.","Bracket IPv6: socks5://[::1]:1080.","Verify the address part is exactly host:port (u.Host) before calling NewHTTPClient.","Check the wrapped error message with %w unwrapping to confirm which address string reached proxy.SOCKS5."],"exampleFix":"// before\nproxyURL := \"socks5://127.0.0.1\" // no port -> dialer creation fails\n\n// after\nproxyURL := \"socks5://127.0.0.1:1080\"","handlingStrategy":"validation","validationCode":"u, err := url.Parse(proxyURL)\nif err != nil { return err }\nif strings.EqualFold(u.Scheme, \"socks5\") || strings.EqualFold(u.Scheme, \"socks5h\") {\n    if u.Port() == \"\" {\n        return fmt.Errorf(\"socks5 proxy %q must include :port\", proxyURL)\n    }\n}","typeGuard":null,"tryCatchPattern":"client, err := netproxy.NewHTTPClient(proxyURL, timeout)\nif err != nil && strings.Contains(err.Error(), \"socks5 dialer\") {\n    return fmt.Errorf(\"check socks5 proxy host:port in %q: %w\", proxyURL, err)\n}","preventionTips":["Always include an explicit port for SOCKS proxies.","Bracket IPv6 proxy addresses.","Smoke-test the setting with one request right after saving."],"tags":["proxy","socks5","http-client","configuration"],"backgroundTag":null,"analyzedSha":"ad32144c42455696ea9f14e12168beac3e25f5d2","analyzedAt":"2026-08-15T11:13:23.905Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}