{"record":{"id":"7076b5b364ea9e9c","repo":"t8y2/dbx","slug":"failed-to-enable-tls-in-tdengine-connection-url","errorCode":null,"errorMessage":"failed to enable TLS in TDengine connection URL","messagePattern":"failed to enable TLS in TDengine connection URL","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/tdengine/src/config.rs","lineNumber":33,"sourceCode":"    pub value: String,\n    pub database: String,\n}\n\npub fn build_dsn(params: &ConnectParams) -> Result<BuiltDsn> {\n    if !params.client_cert_path.trim().is_empty() || !params.client_key_path.trim().is_empty() {\n        bail!(\"TDengine Rust WebSocket connector does not support client certificate authentication\");\n    }\n\n    let mut url = if params.connection_string.trim().is_empty() {\n        build_from_fields(params)?\n    } else {\n        normalize_connection_string(params.connection_string.trim(), params.ssl)?\n    };\n\n    apply_connection_fields(&mut url, params)?;\n    merge_query_params(&mut url, &params.url_params);\n    if (params.ssl || !params.ca_cert_path.trim().is_empty()) && url.scheme() == \"ws\" {\n        url.set_scheme(\"wss\").map_err(|_| anyhow::anyhow!(\"failed to enable TLS in TDengine connection URL\"))?;\n    }\n    if !params.ca_cert_path.trim().is_empty() {\n        set_query_param(&mut url, \"tls_mode\", \"verify_identity\");\n        set_query_param(&mut url, \"tls_ca\", params.ca_cert_path.trim());\n    }\n    let database = url\n        .path_segments()\n        .and_then(|mut segments| segments.find(|segment| !segment.is_empty()))\n        .map(|segment| percent_decode_str(segment).decode_utf8_lossy().into_owned())\n        .unwrap_or_default();\n    Ok(BuiltDsn { value: url.into(), database })\n}\n\nfn build_from_fields(params: &ConnectParams) -> Result<Url> {\n    let scheme = if params.ssl { \"wss\" } else { \"ws\" };\n    let host = if params.host.trim().is_empty() { DEFAULT_HOST } else { params.host.trim() };\n    let port = if params.port == 0 { DEFAULT_PORT } else { params.port };\n    let username = if params.username.is_empty() { DEFAULT_USER } else { &params.username };","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/tdengine/src/config.rs#L15-L51","documentation":"Thrown in `build_dsn` when TLS is requested (`ssl` is true or a CA cert path is set) but the connection URL scheme remains \"ws\" and `Url::set_scheme(\"wss\")` fails. In the url crate, set_scheme returns an Err when the scheme cannot be switched (e.g. relative URLs or certain special-scheme constraints), so the driver surfaces this error rather than silently disabling TLS.","triggerScenarios":"Setting `ssl: true` or providing `ca_cert_path` while the normalized connection string/URL ends up with a non-ws-compatible scheme that set_scheme cannot convert to \"wss\"; feeding a malformed or legacy connection string that parses to a URL whose scheme is not \"ws\" yet fails the set_scheme call.","commonSituations":"Mixing a legacy JDBC-style connection string with ssl=true; typos in the connection string leading to an unexpected URL scheme; passing ssl flags with a URL already using an incompatible scheme; older config files with `http://`-style endpoints combined with new TLS options.","solutions":["Inspect the resulting URL scheme in your connection string and ensure it is ws:// so it can be upgraded to wss://.","If TLS is wanted, start from a ws:// (websocket) connection string or omit the explicit scheme and let fields build the DSN.","Remove the legacy/non-websocket scheme from connection_string and pass host/port/ssl fields instead.","If TLS is not intended, drop the ssl flag and ca_cert_path instead of forcing wss."],"exampleFix":"// before\nConnectionParams { connection_string: \"taos://host:6041\".into(), ssl: true, .. }\n// after\nConnectionParams { connection_string: \"ws://host:6041\".into(), ssl: true, .. }","handlingStrategy":"validation","validationCode":"fn validate_tls_target(connection_string: &str, ssl: bool, ca_cert_path: &str) -> Result<(), String> {\n    if !ssl && ca_cert_path.trim().is_empty() {\n        return Ok(());\n    }\n    if !connection_string.trim().starts_with(\"ws://\") && !connection_string.trim().is_empty() {\n        return Err(\"TLS requires a ws:// websocket connection string; got an incompatible scheme\".into());\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"match build_dsn(&params) {\n    Ok(dsn) => connect(&dsn).await,\n    Err(e) if e.to_string().contains(\"failed to enable TLS\") => {\n        eprintln!(\"connection string scheme cannot be upgraded to wss: {e}\");\n        Err(e)\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Use ws:// scheme in connection strings when enabling ssl or ca_cert_path.","Prefer structured fields (host/port/ssl) over raw connection strings to let the driver build the DSN.","Never combine legacy JDBC URLs with TLS flags.","Sanity-check the final DSN scheme in a startup smoke test."],"tags":["tls","url","config","tdengine"],"backgroundTag":"tls-handshake-failed","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}