{"record":{"id":"f091e5fa23060742","repo":"shadowsocks/shadowsocks-rust","slug":"missing-local-dns-addr-or-remote-dns-addr-in-c","errorCode":null,"errorMessage":"missing `local_dns_addr` or `remote_dns_addr` in configuration","messagePattern":"missing `local_dns_addr` or `remote_dns_addr` in configuration","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/shadowsocks-service/src/config.rs","lineNumber":1343,"sourceCode":"\n    fn check_integrity(&self) -> Result<(), Error> {\n        match self.protocol {\n            #[cfg(feature = \"local-tun\")]\n            ProtocolType::Tun => {}\n\n            _ => {\n                if self.addr.is_none() {\n                    let err = Error::new(ErrorKind::MissingField, \"missing `addr` in configuration\", None);\n                    return Err(err);\n                }\n            }\n        }\n\n        match self.protocol {\n            #[cfg(feature = \"local-dns\")]\n            ProtocolType::Dns => {\n                if self.local_dns_addr.is_none() || self.remote_dns_addr.is_none() {\n                    let err = Error::new(\n                        ErrorKind::MissingField,\n                        \"missing `local_dns_addr` or `remote_dns_addr` in configuration\",\n                        None,\n                    );\n                    return Err(err);\n                }\n            }\n            #[cfg(feature = \"local-tunnel\")]\n            ProtocolType::Tunnel => {\n                if self.forward_addr.is_none() {\n                    let err = Error::new(ErrorKind::MissingField, \"missing `forward_addr` in configuration\", None);\n                    return Err(err);\n                }\n            }\n\n            #[cfg(feature = \"local-http\")]\n            ProtocolType::Http => {\n                if !self.mode.enable_tcp() {","sourceCodeStart":1325,"sourceCodeEnd":1361,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/crates/shadowsocks-service/src/config.rs#L1325-L1361","documentation":"During Config::validate() for a local server with ProtocolType::Dns (the local DNS forwarder), the library requires both `local_dns_addr` and `remote_dns_addr` to be set. If either is absent, the configuration is rejected with ErrorKind::MissingField before the DNS local can start. This guard prevents a DNS protocol local from running with no upstream/downstream address to forward between.","triggerScenarios":"Calling Config::validate() (or loading a config file via Config::load and then validating) where config_type is Local, protocol is ProtocolType::Dns, and either local_dns_addr or remote_dns_addr is None in the ServerConfig/config.","commonSituations":"Writing a JSON config with \"protocol\": \"dns\" but forgetting the \"local_dns_addr\" or \"remote_dns_addr\" keys; generating configs programmatically via ConfigBuilder and never calling the corresponding setters; upgrading from an older config format that lacked the DNS address fields.","solutions":["Add both `local_dns_addr` and `remote_dns_addr` to the configuration (e.g. \"local_dns_addr\": \"127.0.0.1:53\", \"remote_dns_addr\": \"8.8.8.8:53\").","In code, set them via the config builder/API before calling validate(): config.local_dns_addr = Some(...); config.remote_dns_addr = Some(...).","If DNS forwarding is not needed, change the local protocol to one that does not require these fields (e.g. socks/http)."],"exampleFix":"// before\n{ \"protocol\": \"dns\", \"local_addr\": \"127.0.0.1:1080\" }\n// after\n{ \"protocol\": \"dns\", \"local_addr\": \"127.0.0.1:1080\", \"local_dns_addr\": \"127.0.0.1:53\", \"remote_dns_addr\": \"8.8.8.8:53\" }","handlingStrategy":"validation","validationCode":"if cfg.protocol == ProtocolType::Dns && (cfg.local_dns_addr.is_none() || cfg.remote_dns_addr.is_none()) {\n    return Err(\"dns protocol requires both `local_dns_addr` and `remote_dns_addr`\");\n}","typeGuard":"fn dns_addrs_set(cfg: &Config) -> bool {\n    cfg.protocol != ProtocolType::Dns || (cfg.local_dns_addr.is_some() && cfg.remote_dns_addr.is_some())\n}","tryCatchPattern":"match Config::load(path) {\n    Ok(cfg) => start(cfg),\n    Err(e) if e.to_string().contains(\"local_dns_addr\") => eprintln!(\"add local_dns_addr/remote_dns_addr to config\"),\n    Err(e) => return Err(e),\n}","preventionTips":["Use a JSON schema or serde default checks to require both fields when protocol == dns.","Lint example configs for protocol-specific required fields.","Call Config::validate() in tests with your shipped configs."],"tags":["config","dns","missing-field"],"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"}