shadowsocks/shadowsocks-rust · error
`local_dns_address` invalid
Error message
`local_dns_address` invalid
What it means
Raised under the `local-dns` feature (and only on non-Unix platforms) when `local_dns_address` cannot be interpreted as a local DNS bind address. On Unix, a failed socket-address parse is treated as a Unix socket path (`NameServerAddr::UnixSocketAddr`); on non-Unix there is no such fallback, so an unparseable value produces this Malformed error.
Source
Thrown at crates/shadowsocks-service/src/config.rs:1985
}
#[cfg(feature = "local-dns")]
if let Some(local_dns_address) = local.local_dns_address {
match local_dns_address.parse::<IpAddr>() {
Ok(ip) => {
local_config.local_dns_addr = Some(NameServerAddr::SocketAddr(SocketAddr::new(
ip,
local.local_dns_port.unwrap_or(53),
)));
}
#[cfg(unix)]
Err(..) => {
local_config.local_dns_addr =
Some(NameServerAddr::UnixSocketAddr(PathBuf::from(local_dns_address)));
}
#[cfg(not(unix))]
Err(..) => {
let err = Error::new(ErrorKind::Malformed, "`local_dns_address` invalid", None);
return Err(err);
}
}
}
#[cfg(feature = "local-dns")]
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)),
});
}View on GitHub (pinned to 8eb0f0a65b)
Solutions
- On non-Unix, set `local_dns_address` to a valid IP:port, e.g. "127.0.0.1:6533" (hostname forms are not accepted).
- Replace Unix-socket paths with a TCP UDP-capable address when porting configs from Linux.
- Include the port explicitly — "127.0.0.1" alone will fail to parse as a SocketAddr.
Example fix
// before
{ "local_dns_address": "127.0.0.1" }
// after
{ "local_dns_address": "127.0.0.1:6533" } Defensive patterns
Strategy: validation
Validate before calling
fn validate_local_dns_address(entry: &serde_json::Value) -> Result<(), String> {
if let Some(a) = entry.get("local_dns_address").and_then(|v| v.as_str()) {
if a.starts_with('/') {
return Err("unix socket paths for local_dns_address only work on unix targets".into());
}
if a.parse::<std::net::SocketAddr>().is_err() {
return Err(format!("local_dns_address '{a}' is not a valid IP:port"));
}
}
Ok(())
} Type guard
fn is_valid_socket_addr(s: &str) -> bool {
s.parse::<std::net::SocketAddr>().is_ok()
} Try / catch
#[cfg(feature = "local-dns")]
match LocalConfig::load_from(config_path) {
Ok(cfg) => start(cfg),
Err(e) if e.to_string().contains("local_dns_address") => {
eprintln!("Use IP:port for local_dns_address on this platform: {e}");
std::process::exit(1);
}
Err(e) => return Err(e.into()),
} Prevention
- On non-Unix targets always use IP:port (e.g. 127.0.0.1:6533), never a socket path.
- Include the port explicitly; bare IPs will not parse.
- When porting Linux configs to Windows/macOS, replace Unix-socket DNS addresses first.
When it happens
Trigger: On Windows/non-Unix: `local_dns_address` set to something that is not a valid SocketAddr, e.g. a Unix socket path like "/var/run/dns.sock", or a malformed address like "127.0.0.1" (missing port) or "localhost:53" (non-IP host).
Common situations: Configs moved from Linux (Unix socket DNS address) to Windows; addresses written as hostnames instead of IP:port; missing port in the address string.
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
- `tcp_redir` invalid
- missing `local_dns_addr` or `remote_dns_addr` in configurati
- `protocol` invalid
- `local_port` cannot be 0
- `local_udp_port` cannot be 0
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/c3a91d00fdcabe00.
Report an issue: GitHub.