shadowsocks/shadowsocks-rust · error

`users[].password` length must be exactly the same as method

Error message

`users[].password` length must be exactly the same as method's key length

What it means

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.

Source

Thrown at crates/shadowsocks-service/src/config.rs:2985

            // Users' key must match key length
            if let Some(user_manager) = server.user_manager() {
                #[cfg(feature = "aead-cipher-2022")]
                if server.method().is_aead_2022() {
                    use shadowsocks::config::method_support_eih;
                    if user_manager.user_count() > 0 && !method_support_eih(server.method()) {
                        let err = Error::new(
                            ErrorKind::Invalid,
                            "server method doesn't support Extended Identity Header (EIH), remove `users`",
                            Some(format!("method {}", server.method())),
                        );
                        return Err(err);
                    }
                }

                let key_len = server.method().key_len();
                for user in user_manager.users_iter() {
                    if user.key().len() != key_len {
                        let err = Error::new(
                            ErrorKind::Malformed,
                            "`users[].password` length must be exactly the same as method's key length",
                            None,
                        );
                        return Err(err);
                    }
                }
            }
        }

        Ok(())
    }
}

impl fmt::Display for Config {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Convert to json

View on GitHub (pinned to 8eb0f0a65b)

Solutions

  1. 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)
  2. 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)
  3. Validate all user key lengths with the server method before deploying the config

Example fix

// before
{"method":"2022-blake3-aes-256-gcm","users":[{"password":"dGVzdA=="}]} // 4-byte key
// after
{"method":"2022-blake3-aes-256-gcm","users":[{"password":"<base64 of 32 random bytes>"}]}
Defensive patterns

Strategy: validation

Validate before calling

let key_len = server.method().key_len();
for user in &server.users {
    assert_eq!(user.key().len(), key_len, "user key must be {} bytes", key_len);
}

Type guard

fn user_key_valid(user: &ServerUser, method: &ServerConfigMethod) -> bool {
    user.key().len() == method.key_len()
}

Try / catch

match config.validate() {
    Err(e) if e.to_string().contains("key length") => eprintln!("regenerate user keys to exactly {} bytes", method.key_len()),
    Err(e) => return Err(e),
    Ok(v) => v,
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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