shadowsocks/shadowsocks-rust · error

invalid replay attack policy

Error message

invalid replay attack policy

What it means

When a Config declares security.replay_attack.policy, the string is parsed into a ReplayAttackPolicy enum during config compilation. If parse::<ReplayAttackPolicy>() fails, this Error with ErrorKind::Invalid is returned. It means the replay-attack policy name in the configuration is not one of the recognized policy values.

Source

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

        if let Some(b) = config.inbound_udp_allow_fragmentation {
            nconfig.inbound_udp_allow_fragmentation = b;
        }

        if let Some(proxy_config) = config.outbound_proxy {
            nconfig.outbound_proxy = proxy_config
                .into_proxies()
                .map_err(|e| Error::new(ErrorKind::Invalid, "invalid outbound_proxy", Some(e)))?;
        }

        // Security
        if let Some(sec) = config.security
            && let Some(replay_attack) = sec.replay_attack
            && let Some(policy) = replay_attack.policy
        {
            match policy.parse::<ReplayAttackPolicy>() {
                Ok(p) => nconfig.security.replay_attack.policy = p,
                Err(..) => {
                    let err = Error::new(ErrorKind::Invalid, "invalid replay attack policy", None);
                    return Err(err);
                }
            }
        }

        if let Some(balancer) = config.balancer {
            nconfig.balancer = BalancerConfig {
                max_server_rtt: balancer.max_server_rtt.map(Duration::from_secs),
                check_interval: balancer.check_interval.map(Duration::from_secs),
                check_best_interval: balancer.check_best_interval.map(Duration::from_secs),
            };
        }

        if let Some(acl_path) = config.acl {
            let acl = match AccessControl::load_from_file(&acl_path) {
                Ok(acl) => acl,
                Err(err) => {
                    let err = Error::new(

View on GitHub (pinned to 8eb0f0a65b)

Solutions

  1. Set security.replay_attack.policy to one of the exact accepted values (see ReplayAttackPolicy::from_str).
  2. Omit security.replay_attack.policy to use the default policy.
  3. Check the crate version's supported policy names; they can differ between releases.
  4. Enable the relevant cargo feature (e.g. replay attack detection) if the policy enum variant is feature-gated.

Example fix

// before
"security": { "replay_attack": { "policy": "disable" } }
// after
"security": { "replay_attack": { "policy": "lru" } }
Defensive patterns

Strategy: validation

Validate before calling

fn validate_replay_policy(v: &str) -> Result<(), String> {
    match v {
        "none" | "lru" | "bloom" => Ok(()),
        other => Err(format!("unknown replay_attack.policy: {other}")),
    }
}

Type guard

fn is_known_replay_policy(v: &str) -> bool {
    matches!(v, "none" | "lru" | "bloom")
}

Try / catch

match config.security.as_ref().and_then(|s| s.replay_attack.as_ref()).and_then(|r| r.policy.as_deref()) {
    Some(p) => match p.parse::<ReplayAttackPolicy>() {
        Ok(_) => {}
        Err(_) => log::error!("replay_attack.policy '{p}' is invalid; use an accepted policy name"),
    },
    None => {}
}

Prevention

When it happens

Trigger: Config field security.replay_attack.policy set to a string that does not parse as a ReplayAttackPolicy (e.g. misspelled or unknown policy name) while building ServiceConfig at crates/shadowsocks-service/src/config.rs:2631.

Common situations: Hand-editing the JSON config and writing policy: "disabled" or "enable" instead of the exact accepted values (e.g. "none", "lru", "bloom" depending on features), or copying config from an older/newer version with different policy names.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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