{"record":{"id":"16b006a9fe106c63","repo":"XTLS/Xray-core","slug":"http-settings-servers-should-have-one-and-only","errorCode":null,"errorMessage":"HTTP settings: \"servers\" should have one and only one member. Multiple endpoints in \"servers\" should use multiple HTTP outbounds and routing balancer instead","messagePattern":"HTTP settings: \"servers\" should have one and only one member\\. Multiple endpoints in \"servers\" should use multiple HTTP outbounds and routing balancer instead","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/http.go","lineNumber":83,"sourceCode":"\tServers  []*HTTPRemoteConfig `json:\"servers\"`\n\tHeaders  map[string]string   `json:\"headers\"`\n}\n\nfunc (v *HTTPClientConfig) Build() (proto.Message, error) {\n\tconfig := new(http.ClientConfig)\n\tif v.Address != nil {\n\t\tv.Servers = []*HTTPRemoteConfig{\n\t\t\t{\n\t\t\t\tAddress: v.Address,\n\t\t\t\tPort:    v.Port,\n\t\t\t},\n\t\t}\n\t\tif len(v.Username) > 0 {\n\t\t\tv.Servers[0].Users = []json.RawMessage{{}}\n\t\t}\n\t}\n\tif len(v.Servers) != 1 {\n\t\treturn 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`)\n\t}\n\tfor _, serverConfig := range v.Servers {\n\t\tif len(serverConfig.Users) > 1 {\n\t\t\treturn 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`)\n\t\t}\n\t\tserver := &protocol.ServerEndpoint{\n\t\t\tAddress: serverConfig.Address.Build(),\n\t\t\tPort:    uint32(serverConfig.Port),\n\t\t}\n\t\tfor _, rawUser := range serverConfig.Users {\n\t\t\tuser := new(protocol.User)\n\t\t\tif v.Address != nil {\n\t\t\t\tuser.Level = v.Level\n\t\t\t\tuser.Email = v.Email\n\t\t\t} else {\n\t\t\t\tif err := json.Unmarshal(rawUser, user); err != nil {\n\t\t\t\t\treturn nil, errors.New(\"failed to parse HTTP user\").Base(err).AtError()\n\t\t\t\t}","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/http.go#L65-L101","documentation":"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.","triggerScenarios":"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.","commonSituations":"Migrating from other proxy clients that accept a server list per outbound; chaining configs where users paste two mirrors into one outbound expecting failover.","solutions":["Keep exactly one object in httpSettings.servers","For multiple upstream proxies, create one HTTP outbound per server and add a routing balancer rule over their outbound tags"],"exampleFix":"// before\n\"servers\": [ {\"address\":\"p1.example\",\"port\":8080}, {\"address\":\"p2.example\",\"port\":8080} ]\n// after\n// outbounds: [{\"tag\":\"http1\",...},{\"tag\":\"http2\",...}] plus routing.balancers with selector [\"http\"]","handlingStrategy":"validation","validationCode":"if len(httpSettings.Servers) != 1 {\n\treturn fmt.Errorf(\"http outbound must declare exactly one server, got %d\", len(httpSettings.Servers))\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Model one-upstream-per-outbound in config templates","Plan multi-proxy setups as multiple outbounds plus a balancer from the start"],"tags":["xray","config","http","outbound","balancing","validation"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}