shadowsocks/shadowsocks-rust · error

{method} don't know how to generate nonce

Error message

{method} don't know how to generate nonce

What it means

Context::generate_nonce panics when the configured cipher method has no nonce-generation implementation compiled in or supported. Nonce generation is only provided for stream, AEAD, and AEAD-2022 cipher features; with none enabled (e.g. method "none"/"plain" with empty nonce handling excluded) there is no way to fill the nonce buffer, so it fails fast. It reflects a feature/cipher mismatch rather than runtime data corruption.

Source

Thrown at crates/shadowsocks/src/context.rs:85

        #[cfg(any(feature = "stream-cipher", feature = "aead-cipher", feature = "aead-cipher-2022"))]
        loop {
            use crate::crypto::utils::random_iv_or_salt;

            random_iv_or_salt(nonce);

            // Salt already exists, generate a new one.
            if unique && self.check_nonce_and_set(method, nonce) {
                continue;
            }

            break;
        }

        #[cfg(not(any(feature = "stream-cipher", feature = "aead-cipher", feature = "aead-cipher-2022")))]
        if !nonce.is_empty() {
            let _ = unique;
            panic!("{method} don't know how to generate nonce");
        }
    }

    /// Check nonce replay
    pub fn check_nonce_replay(&self, method: CipherKind, nonce: &[u8]) -> io::Result<()> {
        if nonce.is_empty() {
            return Ok(());
        }

        #[allow(unused_mut)]
        let mut replay_policy = self.replay_policy;

        #[cfg(feature = "aead-cipher-2022")]
        if method.is_aead_2022() {
            // AEAD-2022 can't be ignored.
            replay_policy = ReplayAttackPolicy::Reject;
        }

View on GitHub (pinned to 8eb0f0a65b)

Solutions

  1. Rebuild with the cipher features enabled: enable `aead-cipher` (and/or `stream-cipher`, `aead-cipher-2022`)
  2. Use a method supported by your build (e.g. plain/none if that is all you need)
  3. Ensure client and server negotiate a method class that exists in both binaries

Example fix

// before (Cargo.toml)
shadowsocks = { version = "...", default-features = false }
// after
shadowsocks = { version = "...", features = ["aead-cipher"] }
Defensive patterns

Strategy: validation

Validate before calling

// only call generate_nonce for builds that support the method's cipher family
#[cfg(any(feature = "stream-cipher", feature = "aead-cipher", feature = "aead-cipher-2022"))]
ctx.generate_nonce(method, &mut nonce, unique);

Prevention

When it happens

Trigger: Calling `Context::generate_nonce` (directly or via from_stream_with_identity / encrypt_payload_aead / encrypt_client_payload_aead_2022 / encrypt_server_payload_aead_2022 / encrypt_payload_stream) when no cipher features (stream-cipher, aead-cipher, aead-cipher-2022) are enabled and the method yields a non-empty nonce requirement.

Common situations: Building shadowsocks-rust with default features disabled and then running with a cipher method; a client/server built without AEAD support negotiating AEAD methods; library users who compile with `default-features = false`.

Related errors


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