{"record":{"id":"7bdd0c54969f6356","repo":"XTLS/Xray-core","slug":"socks-servers-users-should-have-one-member-at-m","errorCode":null,"errorMessage":"SOCKS servers: \"users\" should have one member at most. Multiple members in \"users\" should use multiple SOCKS outbounds and routing balancer instead","messagePattern":"SOCKS servers: \"users\" should have one member at most\\. Multiple members in \"users\" should use multiple SOCKS outbounds and routing balancer instead","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/socks.go","lineNumber":105,"sourceCode":"func (v *SocksClientConfig) Build() (proto.Message, error) {\n\tconfig := new(socks.ClientConfig)\n\tif v.Address != nil {\n\t\tv.Servers = []*SocksRemoteConfig{\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(`SOCKS settings: \"servers\" should have one and only one member. Multiple endpoints in \"servers\" should use multiple SOCKS 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(`SOCKS servers: \"users\" should have one member at most. Multiple members in \"users\" should use multiple SOCKS 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 Socks user\").Base(err).AtError()\n\t\t\t\t}\n\t\t\t}\n\t\t\taccount := new(SocksAccount)\n\t\t\tif v.Address != nil {\n\t\t\t\taccount.Username = v.Username","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/socks.go#L87-L123","documentation":"Xray-core rejects a SOCKS outbound (SocksClientConfig.Build, infra/conf/socks.go:105) whose server entry lists more than one member in the \"users\" array. Modern Xray allows at most one credential per SOCKS server entry; multi-credential setups must be modeled as multiple SOCKS outbounds combined with a routing balancer.","triggerScenarios":"An outbound with protocol \"socks\" whose \"settings\".servers[0].users contains 2 or more objects, e.g. {\"servers\":[{\"address\":\"h\",\"port\":1,\"users\":[{...},{...}]}]}. Only fires in the new \"servers\" form; the legacy address/port/user/pass form cannot trigger it.","commonSituations":"Configs migrated from older Xray/V2Ray forks that permitted per-server user lists; copying a shared outbound template and appending users; scripts that generate one outbound per account but merge users into a single server.","solutions":["Keep exactly one user object per servers[] entry: {\"servers\":[{\"address\":\"1.2.3.4\",\"port\":1080,\"users\":[{\"user\":\"u\",\"pass\":\"p\"}]}]}","If you need multiple credentials/endpoints, define one socks outbound per credential and load-balance them with a routing \"balancers\" entry over their tags","Prefer the simpler flat form: settings:{\"address\":\"1.2.3.4\",\"port\":1080,\"user\":\"u\",\"pass\":\"p\"}, which supports one user implicitly"],"exampleFix":"// before\n\"settings\": { \"servers\": [ { \"address\": \"1.2.3.4\", \"port\": 1080,\n  \"users\": [ {\"user\":\"a\",\"pass\":\"x\"}, {\"user\":\"b\",\"pass\":\"y\"} ] } ] }\n// after\n\"settings\": { \"servers\": [ { \"address\": \"1.2.3.4\", \"port\": 1080,\n  \"users\": [ {\"user\":\"a\",\"pass\":\"x\"} ] } ] }\n// (second credential -> second socks outbound + routing balancer)","handlingStrategy":"validation","validationCode":"// JS: before writing config\nconst s = outbound.settings;\nconst servers = s.servers ?? [{address:s.address, port:s.port, users:s.user?[{user:s.user,pass:s.pass}]:[]}];\nif (servers.length !== 1 || (servers[0].users?.length ?? 0) > 1) throw new Error('socks outbound: one server + at most one user; use multiple outbounds + balancer');","typeGuard":null,"tryCatchPattern":"if (err.message.includes('users\" should have one member')) { /* split into multiple outbounds and re-add balancer */ }","preventionTips":["Generate one socks outbound per credential","Model failover with routing balancers over outbound tags, not user arrays","Lint configs with a generator that encodes the one-user rule"],"tags":["xray","go","config","socks","outbound"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}