XTLS/Xray-core · error

VLESS settings: "vnext" should have one and only one member.

Error message

VLESS settings: "vnext" should have one and only one member. Multiple endpoints in "vnext" should use multiple VLESS outbounds and routing balancer instead

What it means

Thrown by VLessOutboundConfig.Build() when the "vnext" array of a full-style VLESS outbound does not contain exactly one endpoint. Xray requires one server per outbound; load balancing across multiple VLESS servers must be expressed as multiple outbounds plus a routing balancer. Note: if the simplified style is used (top-level "address"), the builder synthesizes a single vnext automatically, so this error only fires in full style with 0 or 2+ vnext entries.

Source

Thrown at infra/conf/vless.go:273

	Testpre    uint32                `json:"testpre"`
	Testseed   []uint32              `json:"testseed"`
	Vnext      []*VLessOutboundVnext `json:"vnext"`
}

// Build implements Buildable
func (c *VLessOutboundConfig) Build() (proto.Message, error) {
	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 {

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Keep exactly one object in "vnext" per outbound
  2. For multiple servers: create one VLESS outbound per server and route through a balancer ("routing":{"balancers":[...]})
  3. Or switch to the simplified style: put "address", "port", "id" at the outbound top level and drop "vnext" entirely

Example fix

// before (one outbound, two servers)
"outbounds": [{ "protocol": "vless", "settings": { "vnext": [ {"address":"a.com","port":443,...}, {"address":"b.com","port":443,...} ] } }]
// after
"outbounds": [
  { "protocol": "vless", "settings": { "vnext": [ {"address":"a.com","port":443,"users":[...]} ] }, "tag": "vless-a" },
  { "protocol": "vless", "settings": { "vnext": [ {"address":"b.com","port":443,"users":[...]} ] }, "tag": "vless-b" }
]
// plus a routing balancer over ["vless-a","vless-b"]
Defensive patterns

Strategy: validation

Validate before calling

func validateSingleVnext(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)
		if _, simplified := settings["address"]; simplified { continue }
		vnext, _ := settings["vnext"].([]any)
		if len(vnext) != 1 {
			return fmt.Errorf("outbound %v: vless vnext must have exactly 1 entry, got %d", m["tag"], len(vnext))
		}
	}
	return nil
}

Type guard

func isSingleVnext(settings map[string]any) bool {
	if _, ok := settings["address"]; ok { return true }
	v, ok := settings["vnext"].([]any)
	return ok && len(v) == 1
}

Prevention

When it happens

Trigger: Full-style outbound with "vnext": [] or with two server objects; also a config that sets neither top-level address nor vnext (len 0).

Common situations: Users migrating from V2Ray 3.x-style configs that allowed multiple vnext entries for failover; aggregating several servers into one outbound 'to save space'; forgetting vnext entirely when streamSettings were filled in.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/86c1f9f81436c8a4. Report an issue: GitHub.