shadowsocks/shadowsocks-rust · error
missing remote_dns_addr
Error message
missing remote_dns_addr
What it means
In DNS relay mode, remote_dns_addr specifies the upstream DNS server that queries are forwarded to through the shadowsocks tunnel. DnsBuilder construction expects it unconditionally (Option::expect), so a dns-mode config without remote_dns_addr panics with "missing remote_dns_addr". Like local_dns_addr, this is a hard requirement for dns mode.
Source
Thrown at crates/shadowsocks-service/src/local/mod.rs:412
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);
}
#[cfg(target_os = "macos")]View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Add remote_dns_addr to the dns-mode config, e.g. remote_dns_addr = "8.8.8.8:53"
- Confirm exact field spelling (remote_dns_addr) — a typo silently produces None
- Ensure both local_dns_addr and remote_dns_addr are present together in dns mode
- Consult the shadowsocks-service dns-tunnel example config for the full required field set
Example fix
# before class = "local" protocol = "dns" local_address = "127.0.0.1:1080" local_dns_addr = "127.0.0.1:8053" # 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.local_dns_addr.is_some(), "dns requires local_dns_addr");
assert!(local_config.remote_dns_addr.is_some(), "dns requires remote_dns_addr");
} Type guard
fn dns_upstream_ok(cfg: &LocalConfig) -> bool {
cfg.protocol != ProtocolType::Dns || cfg.remote_dns_addr.is_some()
} Try / catch
// expect() panics — pre-validate
if !dns_upstream_ok(&config) {
eprintln!("invalid dns config: remote_dns_addr is required (e.g. 8.8.8.8:53)");
std::process::exit(2);
}
let server = LocalServer::new(context, config)?; Prevention
- Check exact key spelling: remote_dns_addr (a truncated key like remote_dns silently yields None)
- Always configure local_dns_addr and remote_dns_addr as a pair in dns mode
- Validate configs with a lint/schema step before deploying to servers
- Compare against the upstream dns-tunnel example whenever upgrading versions
When it happens
Trigger: protocol = "dns" config supplies local_dns_addr but not remote_dns_addr (field absent or misspelled, e.g. `remote_dns` instead of `remote_dns_addr`), causing the expect in LocalServer::new to panic.
Common situations: Hand-written dns configs omitting the upstream server; renaming/regression in config keys after upgrading; automated config generators copying dns sections incompletely.
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 local_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/e4dc655843537ebe.
Report an issue: GitHub.