shadowsocks/shadowsocks-rust · error
`tun_interface_address` invalid
Error message
`tun_interface_address` invalid
What it means
Thrown while parsing a SIP008/JSON local config: the `tun_interface_address` field failed to parse as an IpNet (CIDR network). The library requires a valid IPv4/IPv6 network like `10.0.0.1/24`; anything else is rejected with ErrorKind::Malformed during Config::load_from_json / from (SIP008) processing.
Source
Thrown at crates/shadowsocks-service/src/config.rs:2010
if let Some(client_cache_size) = local.client_cache_size {
local_config.client_cache_size = Some(client_cache_size);
}
#[cfg(feature = "local-dns")]
if let Some(remote_dns_address) = local.remote_dns_address {
let remote_dns_port = local.remote_dns_port.unwrap_or(53);
local_config.remote_dns_addr = Some(match remote_dns_address.parse::<IpAddr>() {
Ok(ip) => Address::from(SocketAddr::new(ip, remote_dns_port)),
Err(..) => Address::from((remote_dns_address, remote_dns_port)),
});
}
#[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")]View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Use CIDR notation with a valid prefix, e.g. `"tun_interface_address": "10.0.0.1/24"`
- Verify the prefix length is valid for the address family (0-32 for IPv4, 0-128 for IPv6)
- If only a plain address is needed, append `/32` (IPv4) or `/128` (IPv6)
Example fix
// before
{"tun_interface_address": "10.0.0.1"}
// after
{"tun_interface_address": "10.0.0.1/24"} 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_address"].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_address") => fix_and_retry(), ... } Prevention
- Always write TUN addresses in CIDR notation
- Validate the JSON with a schema before loading
- Append /32 or /128 when only a host address is intended
When it happens
Trigger: Calling config parsing with a local entry whose `tun_interface_address` is set to a bare IP without a prefix length, a hostname, an empty string, or any string not parseable by `IpNet::from_str`.
Common situations: Copying a TUN address from another tool that uses plain IPs instead of CIDR notation; typos like `10.0.0.1/33`; forgetting the `/prefix` suffix; IPv6 addresses with invalid prefix.
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_destination` 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/5ccc9935d4b995c8.
Report an issue: GitHub.