XTLS/Xray-core · error

HTTP settings: "servers" should have one and only one member

Error message

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

What it means

Thrown by the HTTP outbound config builder when, after optional legacy address-based normalization, the servers array does not contain exactly one entry. Xray's HTTP outbound supports exactly one upstream server per outbound; if you need multiple endpoints you should define multiple HTTP outbounds and load-balance via the router balancer. Zero servers or 2+ servers both trigger this.

Source

Thrown at infra/conf/http.go:83

	Servers  []*HTTPRemoteConfig `json:"servers"`
	Headers  map[string]string   `json:"headers"`
}

func (v *HTTPClientConfig) Build() (proto.Message, error) {
	config := new(http.ClientConfig)
	if v.Address != nil {
		v.Servers = []*HTTPRemoteConfig{
			{
				Address: v.Address,
				Port:    v.Port,
			},
		}
		if len(v.Username) > 0 {
			v.Servers[0].Users = []json.RawMessage{{}}
		}
	}
	if len(v.Servers) != 1 {
		return nil, errors.New(`HTTP settings: "servers" should have one and only one member. Multiple endpoints in "servers" should use multiple HTTP outbounds and routing balancer instead`)
	}
	for _, serverConfig := range v.Servers {
		if len(serverConfig.Users) > 1 {
			return nil, errors.New(`HTTP servers: "users" should have one member at most. Multiple members in "users" should use multiple HTTP outbounds and routing balancer instead`)
		}
		server := &protocol.ServerEndpoint{
			Address: serverConfig.Address.Build(),
			Port:    uint32(serverConfig.Port),
		}
		for _, rawUser := range serverConfig.Users {
			user := new(protocol.User)
			if v.Address != nil {
				user.Level = v.Level
				user.Email = v.Email
			} else {
				if err := json.Unmarshal(rawUser, user); err != nil {
					return nil, errors.New("failed to parse HTTP user").Base(err).AtError()
				}

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Keep exactly one object in httpSettings.servers
  2. For multiple upstream proxies, create one HTTP outbound per server and add a routing balancer rule over their outbound tags

Example fix

// before
"servers": [ {"address":"p1.example","port":8080}, {"address":"p2.example","port":8080} ]
// after
// outbounds: [{"tag":"http1",...},{"tag":"http2",...}] plus routing.balancers with selector ["http"]
Defensive patterns

Strategy: validation

Validate before calling

if len(httpSettings.Servers) != 1 {
	return fmt.Errorf("http outbound must declare exactly one server, got %d", len(httpSettings.Servers))
}

Prevention

When it happens

Trigger: Setting httpSettings.servers with 0 entries or with 2+ entries; or relying on the legacy top-level address form while also populating servers inconsistently so the count ends up != 1.

Common situations: Migrating from other proxy clients that accept a server list per outbound; chaining configs where users paste two mirrors into one outbound expecting failover.

Related errors


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