{"record":{"id":"805f1031b1fe5ceb","repo":"shadowsocks/shadowsocks-rust","slug":"users-password-length-must-be-exactly-the-same","errorCode":null,"errorMessage":"`users[].password` length must be exactly the same as method's key length","messagePattern":"`users\\[\\]\\.password` length must be exactly the same as method's key length","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/shadowsocks-service/src/config.rs","lineNumber":2985,"sourceCode":"            // Users' key must match key length\n            if let Some(user_manager) = server.user_manager() {\n                #[cfg(feature = \"aead-cipher-2022\")]\n                if server.method().is_aead_2022() {\n                    use shadowsocks::config::method_support_eih;\n                    if user_manager.user_count() > 0 && !method_support_eih(server.method()) {\n                        let err = Error::new(\n                            ErrorKind::Invalid,\n                            \"server method doesn't support Extended Identity Header (EIH), remove `users`\",\n                            Some(format!(\"method {}\", server.method())),\n                        );\n                        return Err(err);\n                    }\n                }\n\n                let key_len = server.method().key_len();\n                for user in user_manager.users_iter() {\n                    if user.key().len() != key_len {\n                        let err = Error::new(\n                            ErrorKind::Malformed,\n                            \"`users[].password` length must be exactly the same as method's key length\",\n                            None,\n                        );\n                        return Err(err);\n                    }\n                }\n            }\n        }\n\n        Ok(())\n    }\n}\n\nimpl fmt::Display for Config {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        // Convert to json\n","sourceCodeStart":2967,"sourceCodeEnd":3003,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/crates/shadowsocks-service/src/config.rs#L2967-L3003","documentation":"Raised during server config validation when a user's key (derived from `users[].password`) does not have exactly the same byte length as the server method's key length. AEAD-2022 multi-user mode requires every user key to be exactly the cipher's key size; shadowsocks-service rejects the config otherwise.","triggerScenarios":"Loading a config where any entry in `servers[].users` has a password whose decoded key length differs from server.method().key_len() (e.g. a 16-byte key under 2022-blake3-aes-256-gcm which needs 32 bytes).","commonSituations":"Generating user keys with the wrong size for the cipher; swapping the method between 128- and 256-bit AEAD-2022 variants without regenerating user keys; typos or truncation in base64 keys.","solutions":["Regenerate each user's password as a base64-encoded random key of exactly method.key_len() bytes (16 for aes-128-gcm, 32 for aes-256-gcm / chacha20-poly1305)","Or switch the method to a variant matching the key length you already have (e.g. 2022-blake3-aes-128-gcm for 16-byte keys)","Validate all user key lengths with the server method before deploying the config"],"exampleFix":"// before\n{\"method\":\"2022-blake3-aes-256-gcm\",\"users\":[{\"password\":\"dGVzdA==\"}]} // 4-byte key\n// after\n{\"method\":\"2022-blake3-aes-256-gcm\",\"users\":[{\"password\":\"<base64 of 32 random bytes>\"}]}","handlingStrategy":"validation","validationCode":"let key_len = server.method().key_len();\nfor user in &server.users {\n    assert_eq!(user.key().len(), key_len, \"user key must be {} bytes\", key_len);\n}","typeGuard":"fn user_key_valid(user: &ServerUser, method: &ServerConfigMethod) -> bool {\n    user.key().len() == method.key_len()\n}","tryCatchPattern":"match config.validate() {\n    Err(e) if e.to_string().contains(\"key length\") => eprintln!(\"regenerate user keys to exactly {} bytes\", method.key_len()),\n    Err(e) => return Err(e),\n    Ok(v) => v,\n}","preventionTips":["Generate keys with a helper sized to the method: rand 16 or 32 bytes then base64","Re-validate all user keys whenever the method changes","Store keys with their intended method in deployment tooling"],"tags":["config","shadowsocks","validation","key-length"],"backgroundTag":"invalid-config-value","analyzedSha":"8eb0f0a65b1d976ab6bed5787327ef86529b0435","analyzedAt":"2026-09-09T12:20:43.168Z","contentChangedAt":"2026-09-09T12:20:43.168Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}