fish2018/pansou · error
创建SOCKS5代理失败
Error message
创建SOCKS5代理失败: %w
What it means
In dy4k's createProxyTransport, golang.org/x/net/proxy.SOCKS5 failed to construct a SOCKS5 dialer from the configured socks5:// proxy address, so the function returns the wrapped error. This happens before any connection is attempted — it is a dialer-construction failure, almost always due to a malformed address string.
Solutions
- Log/verify proxyURL; ensure it is exactly host:port after stripping socks5:// (e.g. 127.0.0.1:1080).
- Strip any userinfo before passing to proxy.SOCKS5; if auth is needed, pass it via the *proxy.Auth parameter instead of embedding it in the address.
- Parse the proxy with net.SplitHostPort first and fail fast with a clear config error if it doesn't split.
- Fix the proxy configuration value in the environment/config file.
Example fix
// before
dialer, err := proxy.SOCKS5("tcp", strings.TrimPrefix(proxyURL, "socks5://"), nil, proxy.Direct)
if err != nil {
return nil, fmt.Errorf("创建SOCKS5代理失败: %w", err)
}
// after
addr := strings.TrimPrefix(proxyURL, "socks5://")
if _, _, serr := net.SplitHostPort(addr); serr != nil {
return nil, fmt.Errorf("SOCKS5代理地址缺少端口: %q", proxyURL)
}
dialer, err := proxy.SOCKS5("tcp", addr, nil, proxy.Direct)
if err != nil {
return nil, fmt.Errorf("创建SOCKS5代理失败: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
addr := strings.TrimPrefix(proxyURL, "socks5://")
if err := validateProxyAddr(addr); err != nil {
return fmt.Errorf("bad socks5 proxy %q: %w", proxyURL, err)
}
func validateProxyAddr(addr string) error {
host, port, err := net.SplitHostPort(addr)
if err != nil { return err }
if host == "" || port == "" { return fmt.Errorf("empty host or port") }
return nil
} Type guard
func isSocks5Addr(s string) bool {
_, _, err := net.SplitHostPort(strings.TrimPrefix(s, "socks5://"))
return err == nil
} Prevention
- Validate proxy settings at startup, not per-request.
- Never embed user:pass in a SOCKS5 address; use proxy.Auth.
- Document the expected host:port format in config samples.
- Test the proxy with a real dial in a health check.
When it happens
Trigger: proxyURL starts with socks5:// but the remainder after TrimPrefix is not a valid host:port (missing port, hostname with no port, extra scheme characters, or embedded whitespace), causing net.Dial's address parsing inside proxy.SOCKS5 to fail.
Common situations: Proxy configured as socks5://127.0.0.1 (no port) or socks5://user:pass@host:1080 where credentials are embedded in the address and not stripped; typo in the proxy env/config value; empty proxy string that still matches the prefix by mistake.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/c9b087feca67fb73.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/dy4k/dy4k.go:153
MaxIdleConns: MaxIdleConns,
MaxIdleConnsPerHost: MaxIdleConnsPerHost,
MaxConnsPerHost: MaxConnsPerHost,
IdleConnTimeout: IdleConnTimeout,
DisableKeepAlives: false,
DisableCompression: false,
WriteBufferSize: 16 * 1024,
ReadBufferSize: 16 * 1024,
}
if proxyURL == "" {
return transport, nil
}
if strings.HasPrefix(proxyURL, "socks5://") {
// SOCKS5代理
dialer, err := proxy.SOCKS5("tcp", strings.TrimPrefix(proxyURL, "socks5://"), nil, proxy.Direct)
if err != nil {
return nil, fmt.Errorf("创建SOCKS5代理失败: %w", err)
}
transport.Dial = dialer.Dial
debugPrintf("🔧 [Dy4k DEBUG] 使用SOCKS5代理: %s\n", proxyURL)
} else {
// HTTP代理
parsedURL, err := url.Parse(proxyURL)
if err != nil {
return nil, fmt.Errorf("解析代理URL失败: %w", err)
}
transport.Proxy = http.ProxyURL(parsedURL)
debugPrintf("🔧 [Dy4k DEBUG] 使用HTTP代理: %s\n", proxyURL)
}
return transport, nil
}
// createOptimizedHTTPClient 创建优化的HTTP客户端(支持代理)
func createOptimizedHTTPClient() *http.Client {View on GitHub (pinned to beaa561337)