transact-rs/sqlx · critical
one of the `runtime-*-native-tls` or `runtime-*-rustls` feat
Error message
one of the `runtime-*-native-tls` or `runtime-*-rustls` features must be enabled
What it means
sqlx's TLS connector() in sqlx-core/src/net/tls/mod.rs panics at runtime when a TLS connection is requested but the crate was compiled without any TLS backend feature. sqlx requires exactly one TLS implementation, selected via `runtime-*-native-tls` or `runtime-*-rustls` feature combinations; with neither `_tls-native-tls` nor `_tls-rustls` enabled, there is no connector to build.
Source
Thrown at sqlx-core/src/net/tls/mod.rs:86
#[cfg(feature = "_tls-native-tls")]
pub use self::tls_native_tls::NativeTlsConnector as TlsConnector;
#[cfg(all(feature = "_tls-rustls", not(feature = "_tls-native-tls")))]
pub use self::tls_rustls::RustlsConnector as TlsConnector;
#[cfg(not(any(feature = "_tls-native-tls", feature = "_tls-rustls")))]
#[derive(Debug, Clone)]
pub struct TlsConnector(std::convert::Infallible);
pub async fn connector(config: TlsConfig<'_>) -> crate::Result<TlsConnector> {
#[cfg(feature = "_tls-native-tls")]
return tls_native_tls::connector(config).await;
#[cfg(all(feature = "_tls-rustls", not(feature = "_tls-native-tls")))]
return tls_rustls::connector(config).await;
#[cfg(not(any(feature = "_tls-native-tls", feature = "_tls-rustls")))]
{
_ = config;
panic!("one of the `runtime-*-native-tls` or `runtime-*-rustls` features must be enabled")
}
}
pub async fn handshake<S, Ws>(
socket: S,
hostname: &str,
connector: &TlsConnector,
with_socket: Ws,
) -> crate::Result<Ws::Output>
where
S: Socket,
Ws: WithSocket,
{
#[cfg(feature = "_tls-native-tls")]
return Ok(with_socket
.with_socket(tls_native_tls::handshake(socket, hostname, connector).await?)
.await);
View on GitHub (pinned to 03af8bcc57)
Solutions
- Enable a rustls-based combo: `sqlx = { features = ["runtime-tokio-rustls", "postgres"] }`.
- Or enable native-tls: `features = ["runtime-tokio-native-tls", "postgres"]`.
- Verify with `cargo tree -e features` (or `cargo metadata`) that one `_tls-*` feature is actually active; watch for other crates disabling default features and re-enabling only a bare runtime feature.
- If TLS is genuinely not needed, ensure the connection URL uses `sslmode=disable` so connector() is never invoked — but enabling a TLS feature is still the robust fix.
Example fix
// before (Cargo.toml)
sqlx = { version = "0.8", features = ["runtime-tokio", "postgres"] }
// after
sqlx = { version = "0.8", features = ["runtime-tokio-rustls", "postgres"] } Defensive patterns
Strategy: validation
Validate before calling
// Verify a TLS backend is enabled at build time:
// Cargo.toml
[features]
default = ["runtime-tokio-rustls"]
// or assert in main.rs before connecting:
#[cfg(not(any(feature = "runtime-tokio-rustls", feature = "runtime-tokio-native-tls")))]
compile_error!("select a TLS runtime feature"); Prevention
- Always pair runtime features with -rustls or -native-tls
- Check `cargo tree -e features | grep _tls` after dependency changes
- Centralize the sqlx dependency in one workspace crate so features are unified
When it happens
Trigger: Calling `sqlx::any::connect` / `PgPool::connect` etc. with a `postgres://...?sslmode=require` (or default-TLS) URL while the Cargo.toml enables only a runtime feature (e.g. `runtime-tokio`) without any `-native-tls`/`-rustls` suffix.
Common situations: Fresh project where the developer added `sqlx = { version = "...", features = ["runtime-tokio", "postgres"] }` and forgot the TLS feature; Docker release builds that trimmed features; upgrading sqlx and old feature names no longer mapping to TLS backends.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- one of the `runtime` features of SQLx must be enabled
- No drivers installed. Please see the documentation in `sqlx:
- Cannot use both flatten and json
- Cannot use both try from and json nullable
- this functionality requires a Tokio context
AI-assisted analysis of transact-rs/sqlx@03af8bcc57 (2026-09-03).
Data as JSON: /api/errors/3f0313d1c293ac4d.
Report an issue: GitHub.