MHSanaei/3x-ui · warning
not hysteria2
Error message
not hysteria2
What it means
Returned by parseHysteria2 when the parsed URL's scheme is neither 'hysteria2' nor 'hy2'. Like the vless/trojan guards, ParseOutbound only forwards links with those two prefixes, so this indicates a direct call to parseHysteria2 or a custom dispatcher routing a hysteria-variant scheme (hysteria:// v1, hy3://) into it.
Source
Thrown at internal/util/link/outbound.go:435
}
func splitMethodPass(userInfo string) (string, string) {
before, after, ok := strings.Cut(userInfo, ":")
if !ok {
return "2022-blake3-aes-128-gcm", userInfo // guess
}
return before, after
}
// --- hysteria2 ---
func parseHysteria2(link string) (*ParseResult, error) {
u, err := url.Parse(link)
if err != nil {
return nil, err
}
if u.Scheme != "hysteria2" && u.Scheme != "hy2" {
return nil, fmt.Errorf("not hysteria2")
}
auth := u.User.Username()
host := u.Hostname()
port := defaultPort(u.Port(), 443)
params := u.Query()
stream := map[string]any{
"network": "hysteria",
"security": "tls",
"hysteriaSettings": map[string]any{
"version": 2,
"auth": auth,
"udpIdleTimeout": 60,
},
"tlsSettings": map[string]any{
"serverName": params.Get("sni"),
"alpn": splitCommaOrDefault(params.Get("alpn"), []string{"h3"}),
"fingerprint": params.Get("fp"),View on GitHub (pinned to ad32144c42)
Solutions
- Dispatch on the exact prefixes 'hysteria2://' and 'hy2://' (case-normalized), and use ParseOutbound publicly.
- Give hysteria v1 (hysteria://) its own parser — its query params (auth, upmbps, alpn) differ from v2.
- Reject or skip v1 links in batch imports rather than routing them to the v2 parser.
Example fix
// before
case strings.Contains(link, "hysteria"):
return parseHysteria2(link)
// after
case strings.HasPrefix(link, "hysteria2://"), strings.HasPrefix(link, "hy2://"):
return parseHysteria2(link) Defensive patterns
Strategy: validation
Validate before calling
func isHysteria2Link(link string) bool {
u, err := url.Parse(strings.TrimSpace(link))
if err != nil { return false }
s := strings.ToLower(u.Scheme)
return s == "hysteria2" || s == "hy2"
} Prevention
- Route only hysteria2:// and hy2:// links to the v2 parser.
- Give hysteria v1 links their own parser or reject them explicitly.
- Case-normalize schemes before dispatch.
When it happens
Trigger: Routing hysteria v1 links (hysteria://) to parseHysteria2 — v1 has an entirely different param format; dispatching on substring 'hy' or 'hysteria' without the exact prefix; direct parser calls in tests or forks.
Common situations: Subscriptions mixing hysteria v1 and v2 entries; forks adding v1 support and reusing the v2 parser; prefix tables matching 'hy2' case-sensitively while a provider emits 'HY2://'.
Related errors
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/c36798f056735fef.
Report an issue: GitHub.