XTLS/Xray-core · error
Shadowsocks 2022 accept no multi servers
Error message
Shadowsocks 2022 accept no multi servers
What it means
In the legacy (non-2022) Shadowsocks outbound path, the builder iterates over all server entries; Shadowsocks-2022 ciphers are only allowed in the single-server fast path. Encountering a 2022 method while iterating multiple servers triggers this error — 2022 does not support the legacy multi-server array.
Source
Thrown at infra/conf/shadowsocks.go:242
return nil, errors.New("Invalid Shadowsocks port.")
}
if server.Password == "" {
return nil, errors.New("Shadowsocks password is not specified.")
}
config := new(shadowsocks_2022.ClientConfig)
config.Address = server.Address.Build()
config.Port = uint32(server.Port)
config.Method = server.Cipher
config.Key = server.Password
return config, nil
}
}
config := new(shadowsocks.ClientConfig)
for _, server := range v.Servers {
if C.Contains(shadowaead_2022.List, server.Cipher) {
return nil, errors.New("Shadowsocks 2022 accept no multi servers")
}
if server.Address == nil {
return nil, errors.New("Shadowsocks server address is not set.")
}
if server.Port == 0 {
return nil, errors.New("Invalid Shadowsocks port.")
}
if server.Password == "" {
return nil, errors.New("Shadowsocks password is not specified.")
}
account := &shadowsocks.Account{
Password: server.Password,
}
account.CipherType = cipherFromString(server.Cipher)
if account.CipherType == shadowsocks.CipherType_UNKNOWN {
return nil, errors.New("unknown cipher method: ", server.Cipher)
}
View on GitHub (pinned to 7d214f8b09)
Solutions
- Split 2022 servers into their own dedicated outbound with exactly one server.
- Keep only classic AEAD ciphers in any multi-server legacy outbound.
- Prefer separate outbounds + routing balancer for multiple endpoints of any type.
Example fix
// before
"servers": [
{"address": "a.com", "port": 443, "method": "aes-128-gcm", "password": "..."},
{"address": "b.com", "port": 443, "method": "2022-blake3-aes-256-gcm", "password": "..."}
]
// after: separate outbounds per endpoint, each with one server Defensive patterns
Strategy: validation
Validate before calling
var ss2022Prefixes = []string{"2022-blake3-"}
func is2022Cipher(m string) bool {
for _, p := range ss2022Prefixes {
if strings.HasPrefix(m, p) {
return true
}
}
return false
}
func validServers(servers []Server) bool {
if len(servers) > 1 {
for _, s := range servers {
if is2022Cipher(s.Cipher) {
return false
}
}
}
return true
} Prevention
- Never mix 2022 and classic entries in one outbound
When it happens
Trigger: Reaching the legacy loop with a 2022 cipher in any servers entry — practically, a 2022 server entry combined with entries that are not caught by the earlier single-2022 branch, e.g. the first server is classic and a later one uses a 2022 method.
Common situations: Mixing 2022 and classic servers in one outbound; adding a 2022 endpoint to an old multi-server list left over from V2Ray configs.
Related errors
- Shadowsocks server address is not set.
- Invalid Shadowsocks port.
- failed to get outbound handler with tag: ${tag}
- existing tag found: ${tag}
- unsupported domain strategy: {}
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/cedf12c5aa0ea946.
Report an issue: GitHub.