MHSanaei/3x-ui · error
unsupported proxy scheme %q
Error message
unsupported proxy scheme %q
What it means
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.
Source
Thrown at internal/util/netproxy/netproxy.go:61
if parsed.User != nil {
password, _ := parsed.User.Password()
auth = &proxy.Auth{User: parsed.User.Username(), Password: password}
}
dialer, err := proxy.SOCKS5("tcp", parsed.Host, auth, proxy.Direct)
if err != nil {
return nil, fmt.Errorf("create socks5 dialer: %w", err)
}
if contextDialer, ok := dialer.(proxy.ContextDialer); ok {
transport.DialContext = contextDialer.DialContext
} else {
transport.DialContext = func(_ context.Context, network, addr string) (net.Conn, error) {
return dialer.Dial(network, addr)
}
}
case "http", "https":
transport.Proxy = http.ProxyURL(parsed)
default:
return nil, fmt.Errorf("unsupported proxy scheme %q", parsed.Scheme)
}
return &http.Client{Timeout: timeout, Transport: transport}, nil
}
func baseTransport() *http.Transport {
if base, ok := http.DefaultTransport.(*http.Transport); ok {
return base.Clone()
}
return &http.Transport{}
}
View on GitHub (pinned to ad32144c42)
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.
Example fix
// before proxyURL := "127.0.0.1:1080" // no scheme -> unsupported proxy scheme "" // after proxyURL := "socks5://127.0.0.1:1080"
Defensive patterns
Strategy: validation
Validate before calling
var allowedSchemes = map[string]bool{"socks5": true, "socks5h": true, "http": true, "https": true}
func allowedProxyScheme(raw string) bool {
u, err := url.Parse(strings.TrimSpace(raw))
if err != nil { return false }
return u.Scheme != "" && allowedSchemes[strings.ToLower(u.Scheme)]
} Type guard
func allowedProxyScheme(raw string) bool {
u, err := url.Parse(strings.TrimSpace(raw))
if err != nil { return false }
return allowedSchemes[strings.ToLower(u.Scheme)]
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/a604ba1c3efdb906.
Report an issue: GitHub.