shadowsocks/shadowsocks-rust · error
`tun_interface_destination` invalid
Error message
`tun_interface_destination` invalid
What it means
Thrown while parsing a SIP008/JSON local config: the `tun_interface_destination` field failed to parse as an IpNet. The library expects a CIDR network (e.g. `1.2.3.0/24`) used as the TUN route destination; invalid strings yield ErrorKind::Malformed.
Source
Thrown at crates/shadowsocks-service/src/config.rs:2022
#[cfg(feature = "local-tun")]
if let Some(tun_interface_address) = local.tun_interface_address {
match tun_interface_address.parse::<IpNet>() {
Ok(addr) => local_config.tun_interface_address = Some(addr),
Err(..) => {
let err = Error::new(ErrorKind::Malformed, "`tun_interface_address` invalid", None);
return Err(err);
}
}
}
#[cfg(feature = "local-tun")]
if let Some(tun_interface_destination) = local.tun_interface_destination {
match tun_interface_destination.parse::<IpNet>() {
Ok(addr) => local_config.tun_interface_destination = Some(addr),
Err(..) => {
let err =
Error::new(ErrorKind::Malformed, "`tun_interface_destination` invalid", None);
return Err(err);
}
}
}
#[cfg(feature = "local-tun")]
if let Some(tun_interface_name) = local.tun_interface_name {
local_config.tun_interface_name = Some(tun_interface_name);
}
#[cfg(all(feature = "local-tun", unix))]
if let Some(tun_device_fd_from_path) = local.tun_device_fd_from_path {
local_config.tun_device_fd_from_path = Some(From::from(tun_device_fd_from_path));
}
#[cfg(feature = "local")]
if let Some(socks5_auth_config_path) = local.socks5_auth_config_path {
local_config.socks5_auth = Socks5AuthConfig::load_from_file(&socks5_auth_config_path)?;View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Express the destination as CIDR, e.g. `"tun_interface_destination": "1.2.3.0/24"`
- Check the prefix length fits the address family (0-32 / 0-128)
- Replace netmask notation with prefix-length notation
Example fix
// before
{"tun_interface_destination": "10.0.0.0/255.0.0.0"}
// after
{"tun_interface_destination": "10.0.0.0/8"} Defensive patterns
Strategy: validation
Validate before calling
fn valid_ipnet(s: &str) -> bool { s.parse::<ipnet::IpNet>().is_ok() }
// before load: assert config["tun_interface_destination"].as_str().map(valid_ipnet).unwrap_or(true) Type guard
fn is_ipnet(s: &str) -> bool { s.parse::<ipnet::IpNet>().is_ok() } Try / catch
match Config::load_from_json(...) { Err(e) if format!("{e}").contains("tun_interface_destination") => fix_and_retry(), ... } Prevention
- Convert netmask notation to prefix length before writing configs
- Keep a list of valid route destinations in CIDR
- Lint configs for missing /prefix on IP fields
When it happens
Trigger: Config parsing where a local entry has `tun_interface_destination` set to a non-CIDR string: bare IP, hostname, bad prefix length, or empty string.
Common situations: Routing destinations copied as single IPs without prefix; typos in IPv6 networks; mixing up address and netmask forms like `10.0.0.0/255.0.0.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
- `tun_interface_address` invalid
- missing `local_dns_addr` or `remote_dns_addr` in configurati
- missing `forward_addr` in configuration
- TCP mode have to be enabled for http
- malformed `mode`, must be one of `tcp_only`, `udp_only` and
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/9bc9bb083f0ddc0d.
Report an issue: GitHub.