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
- Set security.replay_attack.policy to one of the exact accepted values (see ReplayAttackPolicy::from_str).
- Omit security.replay_attack.policy to use the default policy.
- Check the crate version's supported policy names; they can differ between releases.
- 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
- Copy policy names exactly from the crate docs/examples, never from memory
- Omit the policy field to accept the library default
- Re-check accepted values when upgrading shadowsocks versions
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
- `protocol` invalid
- invalid `mode`
- `server`, `server_port`, `method`, `password` must be provid
- `users[].password` should be base64 encoded
- invalid `tcp_weight`, must be in [0, 1]
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/1a5ee8dfb73354f3.
Report an issue: GitHub.