MHSanaei/3x-ui · warning
bad legacy ss hp
Error message
bad legacy ss hp
What it means
Returned by the legacy ss branch when the base64-decoded payload does contain an '@', but the host:port part after it has no ':' (LastIndex returns -1). The parser now has a host but no way to extract a port, so it refuses rather than inventing one.
Source
Thrown at internal/util/link/outbound.go:398
},
},
}
return &ParseResult{Outbound: ob, Identity: identity}, nil
}
// legacy: whole thing b64
dec, err := base64DecodeFlexible(core)
if err != nil {
return nil, err
}
at = strings.Index(dec, "@")
if at < 0 {
return nil, fmt.Errorf("bad legacy ss")
}
userInfo := dec[:at]
hp := dec[at+1:]
colon := strings.LastIndex(hp, ":")
if colon < 0 {
return nil, fmt.Errorf("bad legacy ss hp")
}
host := hp[:colon]
port, err := strconv.Atoi(hp[colon+1:])
if err != nil {
return nil, fmt.Errorf("bad legacy ss port %q: %w", hp[colon+1:], err)
}
method, pass := splitMethodPass(userInfo)
identity := "ss:" + method + ":" + pass + "@" + host + ":" + strconv.Itoa(port)
ob := Outbound{
"protocol": "shadowsocks",
"tag": remark,
"settings": map[string]any{
"servers": []any{
map[string]any{"address": host, "port": port, "password": pass, "method": method},
},
},
}
return &ParseResult{Outbound: ob, Identity: identity}, nilView on GitHub (pinned to ad32144c42)
Solutions
- Decode and inspect the payload; append the missing ':port' and re-encode.
- Use the SIP002 form going forward — it keeps host and port in clear text and fails more obviously.
- Validate legacy payloads with a regexp like ^[^@]+@[^@]+:\d+$ before parsing in bulk.
Example fix
// before (payload decodes to aes-256-gcm:pass@example.com) ss://YWVzLTI1Ni1nY206cGFzc0BleGFtcGxlLmNvbQ== // after (port appended) ss://YWVzLTI1Ni1nY206cGFzc0BleGFtcGxlLmNvbTo0NDM=
Defensive patterns
Strategy: validation
Validate before calling
var legacySSRe = regexp.MustCompile(`^[^@]+@[^@]+:\d{1,5}$`)
func validLegacySSPayload(link string) bool {
core := strings.TrimPrefix(link, "ss://")
dec, err := base64DecodeFlexible(core)
return err == nil && legacySSRe.MatchString(dec)
} Prevention
- Always append ':port' in legacy ss payloads.
- Migrate links to SIP002 where the port is human-readable.
- Reject port-less entries at import time.
When it happens
Trigger: Decoded payload like 'method:pass@host' (port omitted); truncation that cut ':port'; IPv6 host without brackets so parsing logic still finds no usable colon; whitespace or encoding artifacts swallowing the tail.
Common situations: Hand-built legacy links where the port was forgotten; partially corrupted subscriptions; providers testing with dummy entries.
Related errors
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/641fc9a86b2359e5.
Report an issue: GitHub.