{"record":{"id":"1028e84df2f1c983","repo":"rathole-org/rathole","slug":"missing-tls-config","errorCode":null,"errorMessage":"Missing tls config","messagePattern":"Missing tls config","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/transport/native_tls.rs","lineNumber":32,"sourceCode":"pub struct TlsTransport {\n    tcp: TcpTransport,\n    config: TlsConfig,\n    connector: Option<TlsConnector>,\n    tls_acceptor: Option<TlsAcceptor>,\n}\n\n#[async_trait]\nimpl Transport for TlsTransport {\n    type Acceptor = TcpListener;\n    type RawStream = TcpStream;\n    type Stream = TlsStream<TcpStream>;\n\n    fn new(config: &TransportConfig) -> Result<Self> {\n        let tcp = TcpTransport::new(config)?;\n        let config = config\n            .tls\n            .as_ref()\n            .ok_or_else(|| anyhow!(\"Missing tls config\"))?;\n\n        let connector = match config.trusted_root.as_ref() {\n            Some(path) => {\n                let s = fs::read_to_string(path)\n                    .with_context(|| \"Failed to read the `tls.trusted_root`\")?;\n                let cert = Certificate::from_pem(s.as_bytes())\n                    .with_context(|| \"Failed to read certificate from `tls.trusted_root`\")?;\n                let connector = native_tls::TlsConnector::builder()\n                    .add_root_certificate(cert)\n                    .build()?;\n                Some(TlsConnector::from(connector))\n            }\n            None => {\n                // if no trusted_root is specified, allow TlsConnector to use system default\n                let connector = native_tls::TlsConnector::builder().build()?;\n                Some(TlsConnector::from(connector))\n            }\n        };","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/rathole-org/rathole/blob/a292f7ed5402f840415fc6a53827da2f34337856/src/transport/native_tls.rs#L14-L50","documentation":"The native-tls transport wrapper requires TLS settings to operate. Its `new` constructor takes the `tls` section from TransportConfig, and if it is absent (`config.tls` is None) it returns this error from src/transport/native_tls.rs:32. TLS is not optional when this transport is selected.","triggerScenarios":"Configuring transport type to use native TLS but omitting the `[transport.tls]` block (certificate, key, trusted_root) from the config.","commonSituations":"Selecting the tls transport while copying a plain TCP example config; deleting the tls section during config refactors; version upgrades where the tls block moved under transport and the old location is ignored.","solutions":["Add the `[transport.tls]` section to your config with the required fields (certificate, private key, optionally trusted_root).","Confirm the transport type you intend matches the config: either add tls config or switch to the plain TCP transport.","Check the example configs in the repo for the exact key names (`tls.hostname`, `tls.cert`, etc.).","Validate the config file was loaded from the path you think (watch for stale config copies)."],"exampleFix":"# before\n[transport]\ntype = \"tls\"\n\n# after\n[transport]\ntype = \"tls\"\n[transport.tls]\nhostname = \"example.com\"\ncert = \"cert.pem\"\nkey = \"key.pem\"","handlingStrategy":"validation","validationCode":"let raw = std::fs::read_to_string(config_path)?;\nlet cfg: toml::Value = toml::from_str(&raw)?;\nif cfg.get(\"transport\").and_then(|t| t.get(\"tls\")).is_none() {\n    anyhow::bail!(\"tls transport selected but [transport.tls] is missing\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Start from the official TLS example config","Keep tls block adjacent to transport block to avoid accidental deletion","Validate config before launch"],"tags":["tls","config","transport","missing-config"],"backgroundTag":"missing-required-config-field","analyzedSha":"a292f7ed5402f840415fc6a53827da2f34337856","analyzedAt":"2026-09-07T09:56:55.739Z","contentChangedAt":"2026-09-07T09:56:55.739Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}