{"record":{"id":"f2c435921656a908","repo":"shadowsocks/shadowsocks-rust","slug":"forward-port-cannot-be-missing-or-0","errorCode":null,"errorMessage":"`forward_port` cannot be missing or 0","messagePattern":"`forward_port` cannot be missing or 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/shadowsocks-service/src/config.rs","lineNumber":1935,"sourceCode":"                            None => {\n                                // DNS server runs in `TcpAndUdp` mode by default to maintain backwards compatibility\n                                // see https://github.com/shadowsocks/shadowsocks-rust/issues/1281\n                                let mode = match protocol {\n                                    #[cfg(feature = \"local-dns\")]\n                                    ProtocolType::Dns => Mode::TcpAndUdp,\n                                    _ => global_mode,\n                                };\n\n                                local_config.mode = mode;\n                            }\n                        }\n\n                        #[cfg(feature = \"local-tunnel\")]\n                        if let Some(forward_address) = local.forward_address {\n                            let forward_port = match local.forward_port {\n                                None | Some(0) => {\n                                    let err =\n                                        Error::new(ErrorKind::Malformed, \"`forward_port` cannot be missing or 0\", None);\n                                    return Err(err);\n                                }\n                                Some(p) => p,\n                            };\n\n                            local_config.forward_addr = Some(match forward_address.parse::<IpAddr>() {\n                                Ok(ip) => Address::from(SocketAddr::new(ip, forward_port)),\n                                Err(..) => Address::from((forward_address, forward_port)),\n                            });\n                        }\n\n                        #[cfg(feature = \"local-redir\")]\n                        if let Some(tcp_redir) = local.tcp_redir {\n                            match tcp_redir.parse::<RedirType>() {\n                                Ok(r) => local_config.tcp_redir = r,\n                                Err(..) => {\n                                    let err = Error::new(ErrorKind::Malformed, \"`tcp_redir` invalid\", None);\n                                    return Err(err);","sourceCodeStart":1917,"sourceCodeEnd":1953,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/crates/shadowsocks-service/src/config.rs#L1917-L1953","documentation":"Raised under the `local-tunnel` feature when a local entry specifies `forward_address` (meaning it is a tunnel) but `forward_port` is either absent or 0. A tunnel target needs both a host and a non-zero port, so the config is rejected as Malformed.","triggerScenarios":"Enabling a tunnel local server with `\"forward_address\": \"1.2.3.4\"` but omitting `forward_port`, or setting `\"forward_port\": 0`.","commonSituations":"Tunnel configs copied from examples with the destination port stripped; user forgot the remote service port (e.g. forwarding to a DNS or game server); generated configs where the port variable was empty.","solutions":["Set `forward_port` to the target service's port (1-65535), e.g. 53 for DNS over the tunnel.","Remove `forward_address` if a tunnel is not intended (also consider setting protocol to \"tunnel\" explicitly).","Verify the config file actually contains forward_port — a JSON merge may have dropped it."],"exampleFix":"// before\n{ \"protocol\": \"tunnel\", \"forward_address\": \"8.8.8.8\" }\n// after\n{ \"protocol\": \"tunnel\", \"forward_address\": \"8.8.8.8\", \"forward_port\": 53 }","handlingStrategy":"validation","validationCode":"fn validate_tunnel_target(entry: &serde_json::Value) -> Result<(), String> {\n    if entry.get(\"forward_address\").is_some() {\n        match entry.get(\"forward_port\") {\n            None => return Err(\"forward_address set but forward_port missing\".into()),\n            Some(p) if p.as_u64() == Some(0) => {\n                return Err(\"forward_port cannot be 0\".into());\n            }\n            _ => {}\n        }\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"match LocalConfig::load_from(config_path) {\n    Ok(cfg) => start(cfg),\n    Err(e) if e.to_string().contains(\"forward_port\") => {\n        eprintln!(\"Set a real forward_port (1-65535) for the tunnel: {e}\");\n        std::process::exit(1);\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Remember forward_address and forward_port are a mandatory pair for tunnels.","Use the destination service's well-known port (53 for DNS, etc.).","Validate tunnels before deploy: host present => port must be present and non-zero."],"tags":["config","tunnel","port"],"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-14T16:17:12.679Z"}