{"record":{"id":"d737c11ed87bc16c","repo":"shadowsocks/shadowsocks-rust","slug":"invalid-dnsname-domain","errorCode":null,"errorMessage":"invalid dnsname \"{domain}\"","messagePattern":"invalid dnsname \"(.+?)\"","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/shadowsocks-service/src/net/http_stream.rs","lineNumber":104,"sourceCode":"                        if let Err(err) = store.add(cert) {\n                            warn!(\"failed to add cert (native), error: {}\", err);\n                        }\n                    }\n\n                    store\n                })\n                .with_no_client_auth();\n\n            config.alpn_protocols = vec![b\"h2\".to_vec(), b\"http/1.1\".to_vec()];\n            Arc::new(config)\n        });\n\n        let connector = TlsConnector::from(TLS_CONFIG.clone());\n\n        let host = match ServerName::try_from(domain) {\n            Ok(n) => n,\n            Err(_) => {\n                return Err(io::Error::new(\n                    io::ErrorKind::InvalidInput,\n                    format!(\"invalid dnsname \\\"{domain}\\\"\"),\n                ));\n            }\n        };\n\n        let tls_stream = connector.connect(host.to_owned(), stream).await?;\n\n        let (_, session) = tls_stream.get_ref();\n        let negotiated_http2 = matches!(session.alpn_protocol(), Some(b\"h2\"));\n\n        Ok(Self::Https(tls_stream, negotiated_http2))\n    }\n\n    pub fn negotiated_http2(&self) -> bool {\n        match *self {\n            Self::Http(..) => false,\n            #[cfg(any(feature = \"local-http-native-tls\", feature = \"local-http-rustls\"))]","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/crates/shadowsocks-service/src/net/http_stream.rs#L86-L122","documentation":"connect_https builds a rustls TLS connection and must construct a rustls ServerName from the target domain. If the string is not a valid DNS name (empty, contains invalid characters, is an IP literal in a form rustls rejects, or has trailing dots), it returns InvalidInput with 'invalid dnsname'.","triggerScenarios":"Calling connect_https with a domain that fails ServerName::try_from: empty string, non-ASCII/IDN not pre-punycoded, embedded whitespace or control chars, IP address string (older rustls rejected IP ServerName), or names >253 chars.","commonSituations":"Proxy targets taken from URLs without proper host extraction (keeping scheme or port in the host), internationalized domain names not converted to punycode, IPv6 literal hosts like '[::1]' passed with brackets, or empty host from malformed config.","solutions":["Extract and pass only the bare hostname (strip scheme, port, brackets for IPv6)","Convert IDN to punycode (ASCII) before connecting","If the target is an IP address, upgrade to a rustls version supporting IP ServerName or use a TLS stack path that accepts IPs","Validate/trim the host string before calling connect_https","Log the offending domain to spot config or parsing mistakes"],"exampleFix":"// before\nlet domain = \"https://Example.com:443\";\nconnect_https(domain).await?;\n// after\nlet domain = \"example.com\"; // bare, lowercase, punycoded host\nconnect_https(domain).await?;","handlingStrategy":"validation","validationCode":"fn is_valid_dnsname(host: &str) -> bool {\n    !host.is_empty() && host.len() <= 253\n      && host.split('.').all(|l| !l.is_empty() && l.len() <= 63\n        && l.bytes().all(|b| b.is_ascii_alphanumeric() || b == b'-'))\n}","typeGuard":"fn parse_server_name(host: &str) -> Option<rustls::pki_types::ServerName<'static>> {\n    rustls::pki_types::ServerName::try_from(host.to_string()).ok() }","tryCatchPattern":"match connect_https(domain).await { Err(e) if e.kind()==InvalidInput && e.to_string().contains(\"invalid dnsname\") => bail!(\"bad host in config: {domain}\"), r => r }","preventionTips":["Strip scheme/port/brackets before passing hosts","Punycode internationalized domains","Use bare hostnames from URL parsing libraries (url::Url::host_str)","Upgrade rustls if you must TLS-connect to raw IP addresses"],"tags":["tls","rustls","dns","validation","https"],"backgroundTag":"invalid-identifier-format","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"}