shadowsocks/shadowsocks-rust · error

invalid `tcp_weight`, must be in [0, 1]

Error message

invalid `tcp_weight`, must be in [0, 1]

What it means

Thrown when a server entry specifies `tcp_weight` outside the closed interval [0.0, 1.0]. Weights are used by the manager/balancer to distribute traffic across servers; the library validates the range at config parse time and rejects out-of-range values with ErrorKind::Invalid. This check only runs when `tcp_weight` or `udp_weight` is present.

Source

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

                    }
                }

                if let Some(timeout) = config.timeout.map(Duration::from_secs) {
                    nsvr.set_timeout(timeout);
                }

                if let Some(remarks) = svr.remarks {
                    nsvr.set_remarks(remarks);
                }

                if let Some(id) = svr.id {
                    nsvr.set_id(id);
                }

                if svr.tcp_weight.is_some() || svr.udp_weight.is_some() {
                    let tcp_weight = svr.tcp_weight.unwrap_or(1.0);
                    if !(0.0..=1.0).contains(&tcp_weight) {
                        let err = Error::new(ErrorKind::Invalid, "invalid `tcp_weight`, must be in [0, 1]", None);
                        return Err(err);
                    }
                    let udp_weight = svr.udp_weight.unwrap_or(1.0);
                    if !(0.0..=1.0).contains(&udp_weight) {
                        let err = Error::new(ErrorKind::Invalid, "invalid `udp_weight`, must be in [0, 1]", None);
                        return Err(err);
                    }
                    let mut weight = ServerWeight::new();
                    weight.set_tcp_weight(tcp_weight);
                    weight.set_udp_weight(udp_weight);
                    nsvr.set_weight(weight);
                }

                let mut server_instance = ServerInstanceConfig::with_server_config(nsvr);

                if let Some(acl_path) = svr.acl {
                    let acl = match AccessControl::load_from_file(&acl_path) {
                        Ok(acl) => acl,

View on GitHub (pinned to 8eb0f0a65b)

Solutions

  1. Clamp the value into [0.0, 1.0] (e.g. 150 -> 1.0, 30 -> 0.3)
  2. Use 0.0 to give a server no TCP traffic rather than a negative number
  3. Remove `tcp_weight` to use the default weight of 1.0

Example fix

// before
{"server": "1.2.3.4", "server_port": 8388, "method": "aes-256-gcm", "password": "pw", "tcp_weight": 150}
// after
{"server": "1.2.3.4", "server_port": 8388, "method": "aes-256-gcm", "password": "pw", "tcp_weight": 1.0}
Defensive patterns

Strategy: validation

Validate before calling

if let Some(w) = svr.get("tcp_weight").and_then(|w| w.as_f64()) {
    assert!((0.0..=1.0).contains(&w), "tcp_weight {w} out of [0,1]");
}

Type guard

fn valid_tcp_weight(w: f64) -> bool { (0.0..=1.0).contains(&w) }

Try / catch

let tcp_weight = svr.tcp_weight.unwrap_or(1.0);
if !(0.0..=1.0).contains(&tcp_weight) {
    eprintln!("clamping tcp_weight {tcp_weight} to [0,1]");
}

Prevention

When it happens

Trigger: Setting `"tcp_weight": 1.5`, `"tcp_weight": -0.2`, or any value >1 or <0 in a server entry while `tcp_weight`/`udp_weight` fields are used.

Common situations: Confusing percentage-style weights (0-100) with the normalized 0-1 scale; negative values intended as 'disable' (use 0.0 instead); copy-pasting weights from other load balancers with different ranges.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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