{"record":{"id":"15cbca6bf3e1365b","repo":"XTLS/Xray-core","slug":"shadowsocks-password-is-not-specified","errorCode":null,"errorMessage":"Shadowsocks password is not specified.","messagePattern":"Shadowsocks password is not specified\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/shadowsocks.go","lineNumber":75,"sourceCode":"\n\tif C.Contains(shadowaead_2022.List, v.Cipher) {\n\t\treturn buildShadowsocks2022(v)\n\t}\n\n\tconfig := new(shadowsocks.ServerConfig)\n\tconfig.Network = v.NetworkList.Build()\n\n\tif v.Users != nil {\n\t\tif len(v.Users) > 0 {\n\t\t\tconfig.Users = make([]*protocol.User, len(v.Users))\n\t\t\tprocessUser := func(idx int) error {\n\t\t\t\tuser := v.Users[idx]\n\t\t\t\taccount := &shadowsocks.Account{\n\t\t\t\t\tPassword:   user.Password,\n\t\t\t\t\tCipherType: cipherFromString(user.Cipher),\n\t\t\t\t}\n\t\t\t\tif account.Password == \"\" {\n\t\t\t\t\treturn errors.New(\"Shadowsocks password is not specified.\")\n\t\t\t\t}\n\t\t\t\tif account.CipherType < shadowsocks.CipherType_AES_128_GCM ||\n\t\t\t\t\taccount.CipherType > shadowsocks.CipherType_XCHACHA20_POLY1305 {\n\t\t\t\t\treturn errors.New(\"unsupported cipher method: \", user.Cipher)\n\t\t\t\t}\n\t\t\t\tconfig.Users[idx] = &protocol.User{\n\t\t\t\t\tEmail:   user.Email,\n\t\t\t\t\tLevel:   uint32(user.Level),\n\t\t\t\t\tAccount: serial.ToTypedMessage(account),\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tif err := task.ParallelForN(len(v.Users), processUser); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t} else {\n\t\taccount := &shadowsocks.Account{","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/shadowsocks.go#L57-L93","documentation":"While building a multi-user Shadowsocks inbound server config, each entry in 'users' must carry a non-empty 'password'. This error is returned from the per-user builder when user.Password is empty, aborting the parallel build of the users array.","triggerScenarios":"A Shadowsocks inbound with a 'users' array where at least one element omits 'password' (or sets it to \"\"): {\"password\": \"\", \"cipher\": \"aes-128-gcm\"} or a user object with only method/level filled.","commonSituations":"Copy-pasting user templates and forgetting the password; templating configs (Jinja/Ansible) where the password variable is empty; YAML with a commented-out password line.","solutions":["Add a non-empty 'password' to every entry of the inbound's 'users' array.","If the config was generated, check the generator's variable source for empty password values.","Verify no user entry accidentally has 'password' misspelled (e.g. 'pass' or 'passphrase')."],"exampleFix":"// before\n\"settings\": {\n  \"users\": [\n    {\"cipher\": \"aes-128-gcm\", \"level\": 0}\n  ]\n}\n\n// after\n\"settings\": {\n  \"users\": [\n    {\"cipher\": \"aes-128-gcm\", \"password\": \"my-secret\", \"level\": 0}\n  ]\n}","handlingStrategy":"validation","validationCode":"func validUsers(users []User) bool {\n    for _, u := range users {\n        if u.Password == \"\" {\n            return false\n        }\n    }\n    return true\n}","typeGuard":"func hasPassword(u map[string]any) bool {\n    p, ok := u[\"password\"].(string)\n    return ok && p != \"\"\n}","tryCatchPattern":null,"preventionTips":["Validate all user entries before writing the config","Fail fast in config generators when password variables are empty"],"tags":["shadowsocks","config","inbound","users","password"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}