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

  1. Set local_dns_addr in the dns-mode local config, e.g. local_dns_addr = "127.0.0.1:8053"
  2. Also verify remote_dns_addr is set (it is expected on the next line and would panic similarly)
  3. Validate the config with shadowsocks' config validation before launch
  4. 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 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


AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09). Data as JSON: /api/errors/319d178d357f31ef. Report an issue: GitHub.