shadowsocks/shadowsocks-rust · error

missing `addr` in configuration

Error message

missing `addr` in configuration

What it means

shadowsocks-service's Config checker validates LocalConfig before running the local service: every ProtocolType except Tun must have `addr` (the local listening address) set, since TUN operates on a virtual interface instead of a socket. Missing it yields ErrorKind::MissingField with this message, propagated from check() / from_url. (The compile_regex/from_url references in the metadata point at the shared Error type, not this specific message.)

Source

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

            fake_dns_database_path: None,
        }
    }

    /// Create a new `LocalConfig` with listen address
    pub fn new_with_addr(addr: ServerAddr, protocol: ProtocolType) -> Self {
        let mut config = Self::new(protocol);
        config.addr = Some(addr);
        config
    }

    fn check_integrity(&self) -> Result<(), Error> {
        match self.protocol {
            #[cfg(feature = "local-tun")]
            ProtocolType::Tun => {}

            _ => {
                if self.addr.is_none() {
                    let err = Error::new(ErrorKind::MissingField, "missing `addr` in configuration", None);
                    return Err(err);
                }
            }
        }

        match self.protocol {
            #[cfg(feature = "local-dns")]
            ProtocolType::Dns => {
                if self.local_dns_addr.is_none() || self.remote_dns_addr.is_none() {
                    let err = Error::new(
                        ErrorKind::MissingField,
                        "missing `local_dns_addr` or `remote_dns_addr` in configuration",
                        None,
                    );
                    return Err(err);
                }
            }
            #[cfg(feature = "local-tunnel")]

View on GitHub (pinned to 8eb0f0a65b)

Solutions

  1. Set the local listening address: `config.local.addr = Some("127.0.0.1:1080".parse()?)` before check()
  2. Add `local_addr` (and/or `local_address`+`local_port` as required by your version) to the config JSON
  3. If you intentionally don't need a listening address, use ProtocolType::Tun (requires the local-tun feature)
  4. For from_url usage, ensure the sslocal:// URL includes the bind address/port

Example fix

// before
let mut local = LocalConfig::new(ProtocolType::Socks);
// after
let mut local = LocalConfig::new(ProtocolType::Socks);
local.addr = Some("127.0.0.1:1080".parse().unwrap());
Defensive patterns

Strategy: validation

Validate before calling

// before calling config.check()
for local in &config.local {
    if local.protocol != ProtocolType::Tun && local.addr.is_none() {
        return Err("local.addr must be set for non-TUN protocols");
    }
}

Try / catch

// this one is a returned error, so handle it normally:
if let Err(err) = config.check() {
    eprintln!("invalid config: {err}");
    std::process::exit(1);
}

Prevention

When it happens

Trigger: Building LocalConfig programmatically (or via Config::from_url) without setting `local.addr`, then calling Config::check()/ConfigType::Local validation; a config JSON missing the `local_addr` field for a socks/http/dns/tunnel/redir protocol; a sslocal:// URL without the address component.

Common situations: Hand-written config.json with `"local_port"` but no address fields in the expected shape; API users of shadowsocks-service crate constructing LocalConfig::new(ProtocolType::Dns) and forgetting `config.addr = Some(...)`; tooling generating configs dropping empty fields.

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/6837ca4eb0a6043e. Report an issue: GitHub.