{"record":{"id":"e4dc655843537ebe","repo":"shadowsocks/shadowsocks-rust","slug":"missing-remote-dns-addr","errorCode":null,"errorMessage":"missing remote_dns_addr","messagePattern":"missing remote_dns_addr","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/shadowsocks-service/src/local/mod.rs","lineNumber":412,"sourceCode":"                    server_builder.set_tcp_redir(local_config.tcp_redir);\n                    server_builder.set_udp_redir(local_config.udp_redir);\n                    if let Some(udp_addr) = local_config.udp_addr {\n                        server_builder.set_udp_bind_addr(udp_addr);\n                    }\n\n                    let server = server_builder.build().await?;\n                    local_server.redir_servers.push(server);\n                }\n                #[cfg(feature = \"local-dns\")]\n                ProtocolType::Dns => {\n                    let client_addr = match local_config.addr {\n                        Some(a) => a,\n                        None => return Err(io::Error::other(\"dns requires local address\")),\n                    };\n\n                    let mut server_builder = {\n                        let local_addr = local_config.local_dns_addr.expect(\"missing local_dns_addr\");\n                        let remote_addr = local_config.remote_dns_addr.expect(\"missing remote_dns_addr\");\n                        let client_cache_size = local_config.client_cache_size.unwrap_or(5);\n\n                        DnsBuilder::with_context(\n                            context.clone(),\n                            client_addr,\n                            local_addr.clone(),\n                            remote_addr.clone(),\n                            balancer,\n                            client_cache_size,\n                        )\n                    };\n                    server_builder.set_mode(local_config.mode);\n\n                    #[cfg(target_os = \"macos\")]\n                    if let Some(n) = local_config.launchd_tcp_socket_name {\n                        server_builder.set_launchd_tcp_socket_name(n);\n                    }\n                    #[cfg(target_os = \"macos\")]","sourceCodeStart":394,"sourceCodeEnd":430,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/crates/shadowsocks-service/src/local/mod.rs#L394-L430","documentation":"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.","triggerScenarios":"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.","commonSituations":"Hand-written dns configs omitting the upstream server; renaming/regression in config keys after upgrading; automated config generators copying dns sections incompletely.","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"],"exampleFix":"# before\nclass = \"local\"\nprotocol = \"dns\"\nlocal_address = \"127.0.0.1:1080\"\nlocal_dns_addr = \"127.0.0.1:8053\"\n# after\nclass = \"local\"\nprotocol = \"dns\"\nlocal_address = \"127.0.0.1:1080\"\nlocal_dns_addr = \"127.0.0.1:8053\"\nremote_dns_addr = \"8.8.8.8:53\"","handlingStrategy":"validation","validationCode":"if local_config.protocol == ProtocolType::Dns {\n    assert!(local_config.local_dns_addr.is_some(), \"dns requires local_dns_addr\");\n    assert!(local_config.remote_dns_addr.is_some(), \"dns requires remote_dns_addr\");\n}","typeGuard":"fn dns_upstream_ok(cfg: &LocalConfig) -> bool {\n    cfg.protocol != ProtocolType::Dns || cfg.remote_dns_addr.is_some()\n}","tryCatchPattern":"// expect() panics — pre-validate\nif !dns_upstream_ok(&config) {\n    eprintln!(\"invalid dns config: remote_dns_addr is required (e.g. 8.8.8.8:53)\");\n    std::process::exit(2);\n}\nlet server = LocalServer::new(context, config)?;","preventionTips":["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"],"tags":["dns","configuration","missing-field","panic"],"backgroundTag":"missing-required-config-field","analyzedSha":"8eb0f0a65b1d976ab6bed5787327ef86529b0435","analyzedAt":"2026-09-09T12:20:43.168Z","contentChangedAt":"2026-09-09T12:20:43.168Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}