XTLS/Xray-core · error
Shadowsocks settings: "servers" should have one and only one
Error message
Shadowsocks settings: "servers" should have one and only one member. Multiple endpoints in "servers" should use multiple Shadowsocks outbounds and routing balancer instead
What it means
The legacy Shadowsocks outbound 'servers' array must contain exactly one server entry; for load balancing you are expected to define multiple Shadowsocks outbounds plus a routing balancer. If 'servers' has zero or more than one element after the address shorthand normalization, this error is returned.
Source
Thrown at infra/conf/shadowsocks.go:214
}
func (v *ShadowsocksClientConfig) Build() (proto.Message, error) {
errors.PrintNonRemovalDeprecatedFeatureWarning("Shadowsocks (with no Forward Secrecy, etc.)", "VLESS Encryption")
if v.Address != nil {
v.Servers = []*ShadowsocksServerTarget{
{
Address: v.Address,
Port: v.Port,
Level: v.Level,
Email: v.Email,
Cipher: v.Cipher,
Password: v.Password,
},
}
}
if len(v.Servers) != 1 {
return nil, errors.New(`Shadowsocks settings: "servers" should have one and only one member. Multiple endpoints in "servers" should use multiple Shadowsocks outbounds and routing balancer instead`)
}
if len(v.Servers) == 1 {
server := v.Servers[0]
if C.Contains(shadowaead_2022.List, server.Cipher) {
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.")
}
config := new(shadowsocks_2022.ClientConfig)
config.Address = server.Address.Build()
config.Port = uint32(server.Port)View on GitHub (pinned to 7d214f8b09)
Solutions
- Keep exactly one entry in 'servers' (or use the shorthand top-level address/port/password form).
- For multiple endpoints, create one Shadowsocks outbound per endpoint and add a balancer group in routing rules.
- Remove an empty 'servers' array and fill the top-level fields instead.
Example fix
// before
"outbounds": [{
"protocol": "shadowsocks",
"settings": {"servers": [srvA, srvB]}
}]
// after
"outbounds": [
{"tag": "ss-a", "protocol": "shadowsocks", "settings": {"servers": [srvA]}},
{"tag": "ss-b", "protocol": "shadowsocks", "settings": {"servers": [srvB]}}
],
"routing": {"balancers": [{"tag": "ss-bal", "selector": ["ss-a", "ss-b"]}]} Defensive patterns
Strategy: validation
Validate before calling
func validSSOutbound(settings map[string]any) bool {
servers, ok := settings["servers"].([]any)
return ok && len(servers) == 1
} Prevention
- Model multiple endpoints as multiple outbounds + balancer from the start
When it happens
Trigger: A Shadowsocks outbound with a 'servers' array of length != 1, e.g. two endpoints for failover, or an empty array with no top-level address.
Common situations: Old V2Ray configs with multiple servers in one outbound; attempting load-balancing via multiple entries instead of balancers; providing neither 'address' shorthand nor 'servers'.
Related errors
- SOCKS settings: "servers" should have one and only one membe
- Trojan settings: "servers" should have one and only one memb
- VLESS settings: "vnext" should have one and only one member.
- VMess settings: "vnext" should have one and only one member.
- failed to get outbound handler with tag: ${tag}
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/75676628503a4386.
Report an issue: GitHub.