shadowsocks/shadowsocks-rust · error
missing local_dns_addr
Error message
missing local_dns_addr
What it means
In DNS relay mode (protocol = "dns"), LocalConfig.local_dns_addr holds the address the local DNS resolver binds/uses. The builder expects it unconditionally (Option::expect) when constructing DnsBuilder, so a dns-mode config lacking local_dns_addr panics with "missing local_dns_addr". It is a programming/config invariant: dns mode cannot start without it.
Source
Thrown at crates/shadowsocks-service/src/local/mod.rs:411
server_builder.set_mode(local_config.mode);
server_builder.set_tcp_redir(local_config.tcp_redir);
server_builder.set_udp_redir(local_config.udp_redir);
if let Some(udp_addr) = local_config.udp_addr {
server_builder.set_udp_bind_addr(udp_addr);
}
let server = server_builder.build().await?;
local_server.redir_servers.push(server);
}
#[cfg(feature = "local-dns")]
ProtocolType::Dns => {
let client_addr = match local_config.addr {
Some(a) => a,
None => return Err(io::Error::other("dns requires local address")),
};
let mut server_builder = {
let local_addr = local_config.local_dns_addr.expect("missing local_dns_addr");
let remote_addr = local_config.remote_dns_addr.expect("missing remote_dns_addr");
let client_cache_size = local_config.client_cache_size.unwrap_or(5);
DnsBuilder::with_context(
context.clone(),
client_addr,
local_addr.clone(),
remote_addr.clone(),
balancer,
client_cache_size,
)
};
server_builder.set_mode(local_config.mode);
#[cfg(target_os = "macos")]
if let Some(n) = local_config.launchd_tcp_socket_name {
server_builder.set_launchd_tcp_socket_name(n);
}View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Set local_dns_addr in the dns-mode local config, e.g. local_dns_addr = "127.0.0.1:8053"
- Also verify remote_dns_addr is set (it is expected on the next line and would panic similarly)
- Validate the config with shadowsocks' config validation before launch
- Use a config schema/example from the docs for dns mode to ensure all required fields are present
Example fix
# before class = "local" protocol = "dns" local_address = "127.0.0.1:1080" remote_dns_addr = "8.8.8.8:53" # after class = "local" protocol = "dns" local_address = "127.0.0.1:1080" local_dns_addr = "127.0.0.1:8053" remote_dns_addr = "8.8.8.8:53"
Defensive patterns
Strategy: validation
Validate before calling
if local_config.protocol == ProtocolType::Dns {
assert!(local_config.addr.is_some(), "dns requires local address");
assert!(local_config.local_dns_addr.is_some(), "dns requires local_dns_addr");
} Type guard
fn dns_config_ok(cfg: &LocalConfig) -> bool {
cfg.protocol != ProtocolType::Dns || (cfg.addr.is_some() && cfg.local_dns_addr.is_some())
} Try / catch
// expect() panics — validate before construction
if !dns_config_ok(&config) {
eprintln!("invalid dns config: local_dns_addr is required");
std::process::exit(2);
}
let server = LocalServer::new(context, config)?; Prevention
- When switching a local config to protocol = "dns", add local_dns_addr and remote_dns_addr together
- Start from the official dns-tunnel example config rather than editing a socks config in place
- Add a startup config check that dns mode has local address, local_dns_addr, and remote_dns_addr
- Treat LocalServer::new panics as config invariant violations — validate all inputs first
When it happens
Trigger: Configuring protocol = "dns" in the local server config without setting local_dns_addr (e.g. only remote_dns_addr provided), then calling LocalServer::new — the expect fires at construction time.
Common situations: Partial migration from a socks config to dns mode; hand-edited config dropping the field; generated configs not aware that dns mode needs both local_dns_addr and remote_dns_addr.
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
- missing remote_dns_addr
- tunnel requires forward address
- dns
- all plugins are exited. all connections may fail, check your
- unsupported syslog facility: {}
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/319d178d357f31ef.
Report an issue: GitHub.