shadowsocks/shadowsocks-rust · critical

missing any valid servers in configuration

Error message

missing any valid servers in configuration

What it means

When the config's type is a server configuration and the server list is empty, Config::check fails with ErrorKind::MissingField because a shadowsocks server cannot run without at least one server instance (address + password/method).

Source

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

            // 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);
        }

        #[cfg(feature = "local-online-config")]
        if self.config_type.is_online_config() && self.server.is_empty() {
            let err = Error::new(
                ErrorKind::MissingField,
                "missing any valid servers in configuration",
                None,
            );
            return Err(err);
        }

        if self.config_type.is_manager() && self.manager.is_none() {

View on GitHub (pinned to 8eb0f0a65b)

Solutions

  1. Add at least one server entry to the config, e.g. {"server":"0.0.0.0","server_port":8388,"password":"...","method":"aes-256-gcm"}.
  2. Verify you are using the right binary/config pairing: a local-mode config passed to ssserver will not populate server entries; use sslocal for local configs.
  3. Check that your config loader actually parsed the server key (JSON/TOML key mismatch leaves the list empty).

Example fix

// before (server.json)
{ "server": [], "mode": "tcp_and_udp" }

// after
{ "server": [{ "server": "0.0.0.0", "server_port": 8388, "password": "secret", "method": "aes-256-gcm" }], "mode": "tcp_and_udp" }
Defensive patterns

Strategy: validation

Validate before calling

// Rust
let cfg: serde_json::Value = serde_json::from_str(&raw)?;
assert!(cfg.get("server").and_then(|s| s.as_array()).map_or(false, |a| !a.is_empty()), "server config needs at least one server entry");

Try / catch

// Rust
match Config::load_from_file(&path, ConfigType::Server) {
    Ok(c) => c,
    Err(e) if e.to_string().contains("missing any valid servers") => {
        eprintln!("config has no server entries; add one before starting ssserver");
        std::process::exit(1);
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling ssserver (or Config::check) with a config whose config_type is Server and whose server vector is empty — e.g. a server config JSON with no "server" entries, or a config built programmatically without pushing any ServerConfig.

Common situations: Running ssserver with a config file that only contains global options and no server definitions; a template config where the server array was accidentally deleted; programmatic Config construction that forgot to add servers.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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