XTLS/Xray-core · error

VMess vnext: "address" is not set

Error message

VMess vnext: "address" is not set

What it means

Thrown by VMessOutboundConfig.Build() when the single vnext entry has no "address" field (nil Address). Address is the required key of a receiver; without it the server endpoint cannot be constructed. Port and users are checked separately, so a missing address alone is enough to abort the build.

Source

Thrown at infra/conf/vmess.go:144

	config := new(outbound.Config)
	if c.Address != nil {
		c.Receivers = []*VMessOutboundTarget{
			{
				Address: c.Address,
				Port:    c.Port,
				Users:   []json.RawMessage{{}},
			},
		}
	}
	if len(c.Receivers) != 1 {
		return nil, errors.New(`VMess settings: "vnext" should have one and only one member. Multiple endpoints in "vnext" should use multiple VMess outbounds and routing balancer instead`)
	}
	for _, rec := range c.Receivers {
		if len(rec.Users) != 1 {
			return nil, errors.New(`VMess vnext: "users" should have one and only one member. Multiple members in "users" should use multiple VMess outbounds and routing balancer instead`)
		}
		if rec.Address == nil {
			return nil, errors.New(`VMess vnext: "address" is not set`)
		}
		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("invalid VMess user").Base(err)
				}
			}
			account := new(VMessAccount)
			if c.Address != nil {
				account.ID = c.ID

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Add "address":"server.example" to the vnext object
  2. Confirm the key is exactly "address" with a non-empty string or {domain/ip} object value
  3. Use the simplified outbound style ("address" at settings top level) to reduce nesting errors

Example fix

// before
"vnext": [{ "port": 443, "users": [ { "id": "...", "alterId": 0 } ] }]
// after
"vnext": [{ "address": "server.example", "port": 443, "users": [ { "id": "...", "alterId": 0 } ] }]
Defensive patterns

Strategy: validation

Validate before calling

func validateVMessVnextAddress(cfg map[string]any) error {
	outbounds, _ := cfg["outbounds"].([]any)
	for _, ob := range outbounds {
		m, _ := ob.(map[string]any)
		if p, _ := m["protocol"].(string); p != "vmess" { continue }
		settings, _ := m["settings"].(map[string]any)
		vnext, _ := settings["vnext"].([]any)
		for _, v := range vnext {
			ep, _ := v.(map[string]any)
			if a, ok := ep["address"].(string); !ok || a == "" {
				return fmt.Errorf("outbound %v: vmess vnext entry missing address", m["tag"])
			}
		}
	}
	return nil
}

Type guard

func vmessVnextHasAddress(ep map[string]any) bool {
	a, ok := ep["address"]
	if s, isStr := a.(string); isStr { return s != "" }
	_, isObj := a.(map[string]any)
	return ok && isObj
}

Prevention

When it happens

Trigger: "vnext":[{"port":443,"users":[...]}] with the address key absent, null, or misspelled ("server", "host", "add").

Common situations: Converting share links (vmess:// base64) to JSON by hand and dropping the add field; template placeholders never filled in; field-name drift between tools.

Related errors


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