{"record":{"id":"9154da2cb1ed1126","repo":"shadowsocks/shadowsocks-rust","slug":"password-is-required-for-server-svr-addr-9154da","errorCode":null,"errorMessage":"`password` is required for server {svr_addr}","messagePattern":"`password` is required for server (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/service/server.rs","lineNumber":349,"sourceCode":"        };\n\n        if let Some(svr_addr) = matches.get_one::<String>(\"SERVER_ADDR\") {\n            let method = matches\n                .get_one::<String>(\"ENCRYPT_METHOD\")\n                .map(|x| x.parse::<CipherKind>().expect(\"method\"))\n                .expect(\"`method` is required\");\n\n            let password = match matches.get_one::<String>(\"PASSWORD\") {\n                Some(pwd) => read_variable_field_value(pwd).into(),\n                None => {\n                    // NOTE: svr_addr should have been checked by crate::vparser\n                    if method.is_none() {\n                        // If method doesn't need a key (none, plain), then we can leave it empty\n                        String::new()\n                    } else {\n                        match crate::password::read_server_password(svr_addr) {\n                            Ok(pwd) => pwd,\n                            Err(..) => panic!(\"`password` is required for server {svr_addr}\"),\n                        }\n                    }\n                }\n            };\n\n            let svr_addr = svr_addr.parse::<ServerAddr>().expect(\"server-addr\");\n            let timeout = matches.get_one::<u64>(\"TIMEOUT\").map(|x| Duration::from_secs(*x));\n\n            let mut sc = match ServerConfig::new(svr_addr, password, method) {\n                Ok(sc) => sc,\n                Err(err) => {\n                    panic!(\"failed to create ServerConfig, error: {}\", err);\n                }\n            };\n            if let Some(timeout) = timeout {\n                sc.set_timeout(timeout);\n            }\n","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/src/service/server.rs#L331-L367","documentation":"When starting ssserver from CLI flags, if `--password` is not supplied and the chosen encryption method requires a key (anything other than none/plain), the code falls back to reading the password interactively / from the environment via read_server_password; if that also fails, it panics. Encryption methods that derive a key cannot run without a shared password.","triggerScenarios":"Running `ssserver -s 0.0.0.0:8388 -m aes-256-gcm` without `--password` and without SS_PASSWORD-derived interactive/env input available (non-interactive stdin, no TTY); `--password` pointing at a variable field that fails to resolve.","commonSituations":"Running ssserver under systemd/docker where stdin is not a TTY so the interactive password prompt can't be answered; CI scripts that forgot the password flag; method changed from `none` to an AEAD cipher in a script that never set a password.","solutions":["Pass the password explicitly: `ssserver -s 0.0.0.0:8388 -m aes-256-gcm --password '...'`","Use environment-variable password syntax supported by the binary (e.g. --password '$SS_PASSWORD') in non-interactive environments","Run ssserver interactively once so the password prompt can be answered and stored","If no encryption is intended, use `-m none` so an empty password is allowed"],"exampleFix":"// before\nssserver -s 0.0.0.0:8388 -m aes-256-gcm\n// after\nssserver -s 0.0.0.0:8388 -m aes-256-gcm --password '$SS_SERVER_PASSWORD'","handlingStrategy":"validation","validationCode":"if !args.contains(&\"--password\") && method != \"none\" {\n    if std::env::var(\"SS_PASSWORD\").is_err() && std::io::stdin().is_terminal() == false {\n        eprintln!(\"refusing to start: password required for method {method} in non-interactive mode\");\n        std::process::exit(2);\n    }\n}","typeGuard":null,"tryCatchPattern":"// panic is not catchable in stable Rust; when spawning check output:\nlet out = Command::new(\"ssserver\").args(&args).output()?;\nif !out.status.success() && String::from_utf8_lossy(&out.stderr).contains(\"`password` is required\") { /* surface credential error */ }","preventionTips":["Always pass --password (or env-var password syntax) when the cipher is not `none`","Avoid interactive password prompts in systemd/docker: set the password via environment and reference it","Store the method+password pair together in one config to keep them in sync"],"tags":["cli","configuration","password","encryption"],"backgroundTag":"missing-credentials","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"}