XTLS/Xray-core · error
VLESS vnext: "users" should have one and only one member. Mu
Error message
VLESS vnext: "users" should have one and only one member. Multiple members in "users" should use multiple VLESS outbounds and routing balancer instead
What it means
Thrown by VLessOutboundConfig.Build() when the "users" array inside a vnext entry does not contain exactly one member. One VLESS outbound authenticates as exactly one user; multiple credentials must be split across multiple outbounds (optionally behind a routing balancer). An empty users array is rejected for the same reason.
Source
Thrown at infra/conf/vless.go:280
config := new(outbound.Config)
if c.Address != nil {
c.Vnext = []*VLessOutboundVnext{
{
Address: c.Address,
Port: c.Port,
Users: []json.RawMessage{{}},
},
}
}
if len(c.Vnext) != 1 {
return nil, errors.New(`VLESS settings: "vnext" should have one and only one member. Multiple endpoints in "vnext" should use multiple VLESS outbounds and routing balancer instead`)
}
for _, rec := range c.Vnext {
if rec.Address == nil {
return nil, errors.New(`VLESS vnext: "address" is not set`)
}
if len(rec.Users) != 1 {
return nil, errors.New(`VLESS vnext: "users" should have one and only one member. Multiple members in "users" should use multiple VLESS outbounds and routing balancer instead`)
}
spec := &protocol.ServerEndpoint{
Address: rec.Address.Build(),
Port: uint32(rec.Port),
}
for _, rawUser := range rec.Users {
user := new(protocol.User)
if c.Address != nil {
user.Level = c.Level
user.Email = c.Email
} else {
if err := json.Unmarshal(rawUser, user); err != nil {
return nil, errors.New(`VLESS users: invalid user`).Base(err)
}
}
account := new(vless.Account)
if c.Address != nil {
account.Id = c.IdView on GitHub (pinned to 7d214f8b09)
Solutions
- Keep exactly one user object in outbound "users"
- If you need several identities/servers, use multiple outbounds plus a routing balancer
- Make sure the array is not empty — at least one {"id":"uuid","encryption":"none"} is required
Example fix
// before
"users": [ {"id":"uuid-a","encryption":"none"}, {"id":"uuid-b","encryption":"none"} ]
// after
"users": [ {"id":"uuid-a","encryption":"none"} ] Defensive patterns
Strategy: validation
Validate before calling
func validateSingleUserPerVnext(cfg map[string]any) error {
outbounds, _ := cfg["outbounds"].([]any)
for _, ob := range outbounds {
m, _ := ob.(map[string]any)
if p, _ := m["protocol"].(string); p != "vless" { continue }
settings, _ := m["settings"].(map[string]any)
vnext, _ := settings["vnext"].([]any)
for _, v := range vnext {
ep, _ := v.(map[string]any)
users, _ := ep["users"].([]any)
if len(users) != 1 {
return fmt.Errorf("outbound %v: vless vnext.users must have exactly 1 entry, got %d", m["tag"], len(users))
}
}
}
return nil
} Type guard
func hasExactlyOneUser(ep map[string]any) bool {
u, ok := ep["users"].([]any)
return ok && len(u) == 1
} Prevention
- Never paste inbound clients arrays into outbound users
- One credential per outbound; balancers for variety
- Assert len(users)==1 in config generators before emitting JSON
When it happens
Trigger: "vnext":[{"address":"a.com","port":443,"users":[]}] or users with two credential objects; commonly left over from editing an inbound clients list into an outbound.
Common situations: Copying the inbound "clients" array (which legitimately holds many users) into the outbound "users" field; deleting a user and leaving an empty array; misunderstanding that outbound users are credentials for dialing out, not for accepting.
Related errors
- VLESS settings: "vnext" should have one and only one member.
- VLESS vnext: "address" is not set
- VLESS users: please add/set "encryption":"none" for every us
- VMess vnext: "users" should have one and only one member. Mu
- unsupported domain strategy: {}
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/b66a4a1919acd6e2.
Report an issue: GitHub.