{"record":{"id":"c6e68b832360fa22","repo":"shadowsocks/shadowsocks-rust","slug":"missing-forward-addr-in-configuration","errorCode":null,"errorMessage":"missing `forward_addr` in configuration","messagePattern":"missing `forward_addr` in configuration","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/shadowsocks-service/src/config.rs","lineNumber":1354,"sourceCode":"            }\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() {\n                    let err = Error::new(ErrorKind::Invalid, \"TCP mode have to be enabled for http\", None);\n                    return Err(err);\n                }\n            }\n\n            _ => {}\n        }\n\n        Ok(())\n    }\n","sourceCodeStart":1336,"sourceCodeEnd":1372,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/crates/shadowsocks-service/src/config.rs#L1336-L1372","documentation":"During Config::validate() for a local server with ProtocolType::Tunnel (the port-forwarding/tunnel local), the `forward_addr` field must be set. If it is None, the config is rejected with ErrorKind::MissingField. A tunnel without a forward address has nowhere to relay traffic, so the library refuses to start it.","triggerScenarios":"Calling Config::validate() (directly or via Config::load) when config_type is Local, protocol is ProtocolType::Tunnel, and forward_addr is None.","commonSituations":"A JSON config with \"protocol\": \"tunnel\" but no \"forward_addr\" key; programmatically built configs missing the forward_addr setter; copying a tunnel config from an example and deleting the destination address.","solutions":["Add `forward_addr` to the tunnel configuration (e.g. \"forward_addr\": \"example.com:443\").","In code, set config.forward_addr = Some(...) before validating.","If tunneling is not intended, switch the local protocol to socks/http/dns as appropriate."],"exampleFix":"// before\n{ \"protocol\": \"tunnel\", \"local_addr\": \"0.0.0.0:8388\" }\n// after\n{ \"protocol\": \"tunnel\", \"local_addr\": \"0.0.0.0:8388\", \"forward_addr\": \"example.com:443\" }","handlingStrategy":"validation","validationCode":"if cfg.protocol == ProtocolType::Tunnel && cfg.forward_addr.is_none() {\n    return Err(\"tunnel protocol requires `forward_addr`\");\n}","typeGuard":"fn tunnel_addr_set(cfg: &Config) -> bool {\n    cfg.protocol != ProtocolType::Tunnel || cfg.forward_addr.is_some()\n}","tryCatchPattern":"match Config::load(path) {\n    Ok(cfg) => start(cfg),\n    Err(e) if e.to_string().contains(\"forward_addr\") => eprintln!(\"tunnel config must set forward_addr\"),\n    Err(e) => return Err(e),\n}","preventionTips":["Always pair protocol=tunnel with forward_addr in templates.","Validate configs in CI before deploying.","Document the required fields per protocol."],"tags":["config","tunnel","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"}