{"record":{"id":"6f83208738207eda","repo":"shadowsocks/shadowsocks-rust","slug":"users-password-should-be-base64-encoded","errorCode":null,"errorMessage":"`users[].password` should be base64 encoded","messagePattern":"`users\\[\\]\\.password` should be base64 encoded","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/shadowsocks-service/src/config.rs","lineNumber":2308,"sourceCode":"                        let err = Error::new(\n                            ErrorKind::Malformed,\n                            \"server config create failed\",\n                            Some(format!(\"{}\", serr)),\n                        );\n                        return Err(err);\n                    }\n                };\n                nsvr.set_source(server_source);\n\n                // Extensible Identity Header, Users\n                if let Some(users) = svr.users {\n                    let mut user_manager = ServerUserManager::new();\n\n                    for user in users {\n                        let user = match ServerUser::with_encoded_key(user.name, &user.password) {\n                            Ok(u) => u,\n                            Err(..) => {\n                                let err = Error::new(\n                                    ErrorKind::Malformed,\n                                    \"`users[].password` should be base64 encoded\",\n                                    None,\n                                );\n                                return Err(err);\n                            }\n                        };\n\n                        user_manager.add_user(user);\n                    }\n\n                    nsvr.set_user_manager(user_manager);\n                }\n\n                match svr.mode {\n                    Some(mode) => match mode.parse::<Mode>() {\n                        Ok(mode) => nsvr.set_mode(mode),\n                        Err(..) => {","sourceCodeStart":2290,"sourceCodeEnd":2326,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/crates/shadowsocks-service/src/config.rs#L2290-L2326","documentation":"Thrown when an EIP (extensible identity providers) entry under `users` in a server config has a `password` field that `ServerUser::with_encoded_key` cannot decode. For AEAD-2022 and multi-user setups, each user's key must be a base64-encoded key of the exact length the cipher requires; any non-base64 or wrong-length string fails with ErrorKind::Malformed.","triggerScenarios":"Loading a config with a `users: [{\"name\": ..., \"password\": ...}]` array where a user's `password` is not valid base64 or does not decode to the required key size (e.g. 32 bytes for 2022-blake3-aes-256-gcm).","commonSituations":"Users pasting plain-text passwords where base64 keys are required; truncated base64 strings from copy-paste; padding/whitespace corruption; generating keys with the wrong `openssl rand -base64` byte count for the cipher.","solutions":["Generate the user key with `openssl rand -base64 32` (or the byte size matching the cipher) and paste it exactly","Ensure the string is valid standard base64 with correct padding","Match the decoded key length to the cipher's key size (16/24/32 bytes depending on cipher)","Keep server and user keys distinct — each user needs its own key"],"exampleFix":"// before\n{\"users\": [{\"name\": \"alice\", \"password\": \"plain-text-secret\"}]}\n// after\n{\"users\": [{\"name\": \"alice\", \"password\": \"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY=\"}]}","handlingStrategy":"validation","validationCode":"for u in &svr[\"users\"].as_array().unwrap() {\n    let decoded = base64::decode(u[\"password\"].as_str().unwrap()).expect(\"users[].password must be base64\");\n    assert!(decoded.len() == 16 || decoded.len() == 32, \"decoded key length {} invalid\", decoded.len());\n}","typeGuard":"fn is_valid_user_key(pw: &str) -> bool {\n    base64::decode(pw).map(|k| k.len() == 16 || k.len() == 32).unwrap_or(false)\n}","tryCatchPattern":"match ServerUser::with_encoded_key(name, pw) {\n    Ok(u) => add(u),\n    Err(_) => eprintln!(\"user '{name}' key must be base64 of a 16/32-byte key\"),\n}","preventionTips":["Distribute keys only as base64 output of `openssl rand -base64 32`","Avoid manual copy-paste truncation of long key strings","Document that users[].password is a base64 key, not a login password"],"tags":["config","shadowsocks","base64","users"],"backgroundTag":"invalid-argument-format","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"}