shadowsocks/shadowsocks-rust · error
balancer.max_server_rtt must be > 0
Error message
balancer.max_server_rtt must be > 0
What it means
During shadowsocks-service configuration validation (Config::check), if balancer.max_server_rtt is set it must represent a duration strictly greater than zero seconds. A zero (or sub-second zero) value would make the balancer's RTT-based server selection logic meaningless, so the config is rejected with ErrorKind::Invalid.
Source
Thrown at crates/shadowsocks-service/src/config.rs:2869
if self.config_type.is_local() {
if self.local.is_empty() {
let err = Error::new(
ErrorKind::MissingField,
"missing `locals` for client configuration",
None,
);
return Err(err);
}
for local_config in &self.local {
local_config.config.check_integrity()?;
}
// Balancer related checks
if let Some(rtt) = self.balancer.max_server_rtt
&& rtt.as_secs() == 0
{
let err = Error::new(ErrorKind::Invalid, "balancer.max_server_rtt must be > 0", None);
return Err(err);
}
if let Some(intv) = self.balancer.check_interval
&& intv.as_secs() == 0
{
let err = Error::new(ErrorKind::Invalid, "balancer.check_interval must be > 0", None);
return Err(err);
}
}
if self.config_type.is_server() && self.server.is_empty() {
let err = Error::new(
ErrorKind::MissingField,
"missing any valid servers in configuration",
None,
);
return Err(err);View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Set max_server_rtt to a positive duration in your config, e.g. max_server_rtt = "500ms" or a value > 0 seconds.
- If you do not want an RTT cap, remove the max_server_rtt key entirely so the check is skipped (it is only validated when Some).
- If the value comes from a generated config/URL source, fix the generator to omit or correctly compute the RTT value.
Example fix
// before (config.toml) [balancer] max_server_rtt = 0 // after [balancer] max_server_rtt = "500ms"
Defensive patterns
Strategy: validation
Validate before calling
// Rust: before loading config
if let Some(rtt) = balancer_max_server_rtt {
assert!(rtt.as_secs() > 0 || rtt.subsec_nanos() > 0, "max_server_rtt must be > 0");
} Prevention
- Never set duration fields to 0 to mean 'disabled' — omit the key instead.
- Express sub-second values with explicit units ("500ms") to avoid unit confusion.
- Lint generated configs for zero durations before deployment.
When it happens
Trigger: Loading or building a Config with config_type local (balancer enabled) where the [balancer] max_server_rtt field is present in the config file/URL but parsed as 0 seconds, e.g. max_server_rtt = 0 or an invalid duration that normalizes to zero, followed by Config::check()/from loading.
Common situations: Hand-edited TOML/JSON config files where the author set max_server_rtt = 0 intending 'unlimited' or 'disabled'; copy-pasted config snippets with placeholder 0 values; URL-based config (ss:// or SIP002/SIP008 plugin params) with rtt=0.
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
- `protocol` invalid
- invalid `mode`
- `server`, `server_port`, `method`, `password` must be provid
- missing `locals` for client configuration
- balancer.check_interval must be > 0
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/6438d068e9e2122f.
Report an issue: GitHub.