shadowsocks/shadowsocks-rust · error

`password` is required for server {svr_addr}

Error message

`password` is required for server {svr_addr}

What it means

When building local server config from CLI (`sslocal --server-addr ...`), if the chosen method needs a key (not none/plain) and the password cannot be read (e.g. not provided via CLI/env and the encrypted-password read fails), create() panics. The library requires a non-empty password for any keyed cipher. It is fail-fast configuration validation.

Source

Thrown at src/service/local.rs:646

        };

        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);
                }
            };
            sc.set_source(ServerSource::CommandLine);
            if let Some(timeout) = timeout {
                sc.set_timeout(timeout);
            }

View on GitHub (pinned to 8eb0f0a65b)

Solutions

  1. Pass the password explicitly: add `--password <pwd>` to the sslocal command line
  2. Set the expected password environment variable (PASSWORD or per-server password env)
  3. Use method `none`/`plain` only for testing when no password is intended
  4. If using encrypted password files, fix the key/env so read_server_password succeeds

Example fix

// before
sslocal --server-addr example.com:8388 --encrypt-method aes-256-gcm
// after
sslocal --server-addr example.com:8388 --encrypt-method aes-256-gcm --password s3cret
Defensive patterns

Strategy: validation

Validate before calling

# fail early with a clear message before invoking sslocal:
[ -n "$PASSWORD" ] || { echo 'PASSWORD is required for keyed ciphers'; exit 1; }

Prevention

When it happens

Trigger: Calling public `LocalConfig/Service create` (from main) for each `--server-addr` entry when `read_server_password(svr_addr)` returns Err and a cipher method requiring a key is set.

Common situations: Running `sslocal --server-addr host:port --encrypt-method aes-256-gcm` without `--password`; password stored in an encrypted/env source that is unavailable; typo in password env variable name.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09). Data as JSON: /api/errors/c73d64db4c1f80ff. Report an issue: GitHub.