{"record":{"id":"3d026e242b35aa7e","repo":"rathole-org/rathole","slug":"missing-tls-config-3d026e","errorCode":null,"errorMessage":"Missing tls config","messagePattern":"Missing tls config","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/transport/rustls.rs","lineNumber":95,"sourceCode":"    Ok(Some(\n        ClientConfig::builder()\n            .with_root_certificates(root_certs)\n            .with_no_client_auth(),\n    ))\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 = load_client_config(config)\n            .unwrap()\n            .map(|c| Arc::new(c).into());\n        let tls_acceptor = load_server_config(config)\n            .unwrap()\n            .map(|c| Arc::new(c).into());\n\n        Ok(TlsTransport {\n            tcp,\n            config: config.clone(),\n            connector,\n            tls_acceptor,\n        })\n    }\n\n    fn hint(conn: &Self::Stream, opt: SocketOpts) {\n        opt.apply(conn.get_ref().0);","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/rathole-org/rathole/blob/a292f7ed5402f840415fc6a53827da2f34337856/src/transport/rustls.rs#L77-L113","documentation":"The rustls transport requires TLS settings. In `new` (src/transport/rustls.rs:95), `config.tls.as_ref().ok_or_else(...)` fails when no tls section exists in TransportConfig, returning this error. Both the client connector and server acceptor are built from this same tls config, so it is mandatory.","triggerScenarios":"Selecting the rustls-based tls transport while `[transport.tls]` is absent from the config file.","commonSituations":"Switching transport implementations (native-tls ↔ rustls features) and assuming config is optional; using a plain-TCP example config with a TLS transport type; stripping the tls section during templating/secret-injection that failed.","solutions":["Add the `[transport.tls]` section with certificate/key (server) and hostname/trusted_root (client).","If TLS is not desired, change transport type to plain tcp.","Ensure the correct config file is being loaded for the intended role (client vs server).","Check the README/example configs for rustls-specific key expectations (PEM formats)."],"exampleFix":"# before\n[transport]\ntype = \"tls\"\n\n# after\n[transport]\ntype = \"tls\"\n[transport.tls]\nhostname = \"example.com\"\ncert = \"server-cert.pem\"\nkey = \"server-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!(\"rustls transport requires [transport.tls] in config\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use PEM-format certs and validate them with openssl before deployment","Keep one canonical config template per transport type","Validate config before launch"],"tags":["rustls","tls","config","transport"],"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"}