t8y2/dbx · error

failed to enable TLS in TDengine connection URL

Error message

failed to enable TLS in TDengine connection URL

What it means

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.

Source

Thrown at agents/drivers/tdengine/src/config.rs:33

    pub value: String,
    pub database: String,
}

pub fn build_dsn(params: &ConnectParams) -> Result<BuiltDsn> {
    if !params.client_cert_path.trim().is_empty() || !params.client_key_path.trim().is_empty() {
        bail!("TDengine Rust WebSocket connector does not support client certificate authentication");
    }

    let mut url = if params.connection_string.trim().is_empty() {
        build_from_fields(params)?
    } else {
        normalize_connection_string(params.connection_string.trim(), params.ssl)?
    };

    apply_connection_fields(&mut url, params)?;
    merge_query_params(&mut url, &params.url_params);
    if (params.ssl || !params.ca_cert_path.trim().is_empty()) && url.scheme() == "ws" {
        url.set_scheme("wss").map_err(|_| anyhow::anyhow!("failed to enable TLS in TDengine connection URL"))?;
    }
    if !params.ca_cert_path.trim().is_empty() {
        set_query_param(&mut url, "tls_mode", "verify_identity");
        set_query_param(&mut url, "tls_ca", params.ca_cert_path.trim());
    }
    let database = url
        .path_segments()
        .and_then(|mut segments| segments.find(|segment| !segment.is_empty()))
        .map(|segment| percent_decode_str(segment).decode_utf8_lossy().into_owned())
        .unwrap_or_default();
    Ok(BuiltDsn { value: url.into(), database })
}

fn build_from_fields(params: &ConnectParams) -> Result<Url> {
    let scheme = if params.ssl { "wss" } else { "ws" };
    let host = if params.host.trim().is_empty() { DEFAULT_HOST } else { params.host.trim() };
    let port = if params.port == 0 { DEFAULT_PORT } else { params.port };
    let username = if params.username.is_empty() { DEFAULT_USER } else { &params.username };

View on GitHub (pinned to c0390bff16)

Solutions

  1. Inspect the resulting URL scheme in your connection string and ensure it is ws:// so it can be upgraded to wss://.
  2. If TLS is wanted, start from a ws:// (websocket) connection string or omit the explicit scheme and let fields build the DSN.
  3. Remove the legacy/non-websocket scheme from connection_string and pass host/port/ssl fields instead.
  4. If TLS is not intended, drop the ssl flag and ca_cert_path instead of forcing wss.

Example fix

// before
ConnectionParams { connection_string: "taos://host:6041".into(), ssl: true, .. }
// after
ConnectionParams { connection_string: "ws://host:6041".into(), ssl: true, .. }
Defensive patterns

Strategy: validation

Validate before calling

fn validate_tls_target(connection_string: &str, ssl: bool, ca_cert_path: &str) -> Result<(), String> {
    if !ssl && ca_cert_path.trim().is_empty() {
        return Ok(());
    }
    if !connection_string.trim().starts_with("ws://") && !connection_string.trim().is_empty() {
        return Err("TLS requires a ws:// websocket connection string; got an incompatible scheme".into());
    }
    Ok(())
}

Try / catch

match build_dsn(&params) {
    Ok(dsn) => connect(&dsn).await,
    Err(e) if e.to_string().contains("failed to enable TLS") => {
        eprintln!("connection string scheme cannot be upgraded to wss: {e}");
        Err(e)
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/7076b5b364ea9e9c. Report an issue: GitHub.