{"record":{"id":"6b2a4e2fd3cd9442","repo":"shadowsocks/shadowsocks-rust","slug":"tcp-mode-have-to-be-enabled-for-http","errorCode":null,"errorMessage":"TCP mode have to be enabled for http","messagePattern":"TCP mode have to be enabled for http","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/shadowsocks-service/src/config.rs","lineNumber":1362,"sourceCode":"                        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\n    // Check if it is a basic format of local\n    pub fn is_basic(&self) -> bool {\n        if self.protocol != ProtocolType::Socks || self.udp_addr.is_some() {\n            return false;\n        }\n\n        #[cfg(feature = \"local-tunnel\")]\n        if self.forward_addr.is_some() {","sourceCodeStart":1344,"sourceCodeEnd":1380,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/crates/shadowsocks-service/src/config.rs#L1344-L1380","documentation":"During Config::validate() for a local HTTP-protocol server, the mode must include TCP. If mode.enable_tcp() is false (e.g. mode is udp_only), the config is rejected with ErrorKind::Invalid. HTTP proxying is inherently TCP-based, so an HTTP local cannot operate in a TCP-less mode.","triggerScenarios":"Calling Config::validate() when config_type is Local, protocol is ProtocolType::Http, and the configured Mode (e.g. Mode::UdpOnly parsed from \"udp_only\") does not enable TCP.","commonSituations":"Setting \"mode\": \"udp_only\" in a config whose \"protocol\" is \"http\"; combining a UDP-only global mode with an HTTP local; accidentally flipping mode after protocol was chosen.","solutions":["Set mode to \"tcp_only\" or \"tcp_and_udp\" in the configuration.","In code, use Mode::TcpOnly or Mode::TcpAndUdp before validating.","If only UDP relay is needed, use a different local protocol (e.g. tunnel) instead of http."],"exampleFix":"// before\n{ \"protocol\": \"http\", \"mode\": \"udp_only\" }\n// after\n{ \"protocol\": \"http\", \"mode\": \"tcp_and_udp\" }","handlingStrategy":"validation","validationCode":"if cfg.protocol == ProtocolType::Http && !cfg.mode.enable_tcp() {\n    return Err(\"http protocol requires a TCP-enabled mode (tcp_only or tcp_and_udp)\");\n}","typeGuard":"fn mode_ok_for_http(cfg: &Config) -> bool {\n    cfg.protocol != ProtocolType::Http || cfg.mode.enable_tcp()\n}","tryCatchPattern":"match Config::load(path) {\n    Ok(cfg) => start(cfg),\n    Err(e) if e.to_string().contains(\"TCP mode have to be enabled\") => eprintln!(\"use tcp_only or tcp_and_udp for http protocol\"),\n    Err(e) => return Err(e),\n}","preventionTips":["Never combine protocol=http with mode=udp_only.","Centralize mode selection so protocol/mode compatibility is checked in one place.","Add a unit test asserting valid protocol/mode combinations."],"tags":["config","http","mode"],"backgroundTag":"invalid-config-value","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"}