shadowsocks/shadowsocks-rust · error
`password` is required for server {svr_addr}
Error message
`password` is required for server {svr_addr} What it means
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.
Source
Thrown at src/service/server.rs:349
};
if let Some(svr_addr) = matches.get_one::<String>("SERVER_ADDR") {
let method = matches
.get_one::<String>("ENCRYPT_METHOD")
.map(|x| x.parse::<CipherKind>().expect("method"))
.expect("`method` is required");
let password = match matches.get_one::<String>("PASSWORD") {
Some(pwd) => read_variable_field_value(pwd).into(),
None => {
// NOTE: svr_addr should have been checked by crate::vparser
if method.is_none() {
// If method doesn't need a key (none, plain), then we can leave it empty
String::new()
} else {
match crate::password::read_server_password(svr_addr) {
Ok(pwd) => pwd,
Err(..) => panic!("`password` is required for server {svr_addr}"),
}
}
}
};
let svr_addr = svr_addr.parse::<ServerAddr>().expect("server-addr");
let timeout = matches.get_one::<u64>("TIMEOUT").map(|x| Duration::from_secs(*x));
let mut sc = match ServerConfig::new(svr_addr, password, method) {
Ok(sc) => sc,
Err(err) => {
panic!("failed to create ServerConfig, error: {}", err);
}
};
if let Some(timeout) = timeout {
sc.set_timeout(timeout);
}
View on GitHub (pinned to 8eb0f0a65b)
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
Example fix
// before ssserver -s 0.0.0.0:8388 -m aes-256-gcm // after ssserver -s 0.0.0.0:8388 -m aes-256-gcm --password '$SS_SERVER_PASSWORD'
Defensive patterns
Strategy: validation
Validate before calling
if !args.contains(&"--password") && method != "none" {
if std::env::var("SS_PASSWORD").is_err() && std::io::stdin().is_terminal() == false {
eprintln!("refusing to start: password required for method {method} in non-interactive mode");
std::process::exit(2);
}
} Try / catch
// panic is not catchable in stable Rust; when spawning check output:
let out = Command::new("ssserver").args(&args).output()?;
if !out.status.success() && String::from_utf8_lossy(&out.stderr).contains("`password` is required") { /* surface credential error */ } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- `password` is required for server {svr_addr}
- failed to create ServerConfig, error: {}
- not supported `protocol` "{p}"
- `local-addr` is required for protocol {}
- failed to create ServerConfig, error: {}
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/9154da2cb1ed1126.
Report an issue: GitHub.