risingwavelabs/risingwave · error
unsupported SSL mode
Error message
unsupported SSL mode
What it means
RisingWave's MySQL CDC connector only accepts a fixed set of SSL modes when building the sqlx MySQL connection pool. The user-supplied cdc_source.ssl_mode value did not map to Disabled, Preferred, or Required, so connect() rejects it before any network I/O. This guards against silently downgrading or misconfiguring TLS for the CDC source.
Source
Thrown at src/connector/src/source/cdc/external/mysql.rs:145
column_descs: Vec<ColumnDesc>,
pk_names: Vec<String>,
}
impl MySqlExternalTable {
pub async fn connect(config: ExternalTableConfig) -> ConnectorResult<Self> {
tracing::debug!("connect to mysql");
let options = MySqlConnectOptions::new()
.username(&config.username)
.password(&config.password)
.host(&config.host)
.port(config.port.parse::<u16>().unwrap())
.database(&config.database)
.ssl_mode(match config.ssl_mode {
SslMode::Disabled => sqlx::mysql::MySqlSslMode::Disabled,
SslMode::Preferred => sqlx::mysql::MySqlSslMode::Preferred,
SslMode::Required => sqlx::mysql::MySqlSslMode::Required,
_ => {
return Err(anyhow!("unsupported SSL mode").into());
}
});
let connection = MySqlPool::connect_with(options).await?;
let mut schema_discovery = SchemaDiscovery::new(connection, config.database.as_str());
// discover system version first
let system_info = schema_discovery.discover_system().await?;
schema_discovery.query = SchemaQueryBuilder::new(system_info.clone());
let schema = Alias::new(config.database.as_str()).into_iden();
let table = Alias::new(config.table.as_str()).into_iden();
let columns = schema_discovery
.discover_columns(schema.clone(), table.clone(), &system_info)
.await?;
let indexes = schema_discovery.discover_indexes(schema, table).await?;
let mut column_descs = vec![];
for col in columns {
let data_type = mysql_type_to_rw_type(&col.col_type)?;View on GitHub (pinned to 6469eb736d)
Solutions
- Change the ssl_mode option in the WITH clause to one of: 'disabled', 'preferred', 'required'.
- Check the RisingWave docs for the exact accepted ssl_mode strings for mysql cdc sources.
- If stronger validation (verify-ca/verify-full) is needed, request/track upstream support; it is not implemented in this code path.
Example fix
// before CREATE TABLE t (...) WITH ( connector = 'mysql-cdc', ssl_mode = 'verify-full' ); // after CREATE TABLE t (...) WITH ( connector = 'mysql-cdc', ssl_mode = 'required' );
Defensive patterns
Strategy: validation
Validate before calling
const VALID_MODES = ["disabled", "preferred", "required"];
if (!VALID_MODES.includes(options.ssl_mode?.toLowerCase())) {
throw new Error(`ssl_mode must be one of ${VALID_MODES.join("/")}, got: ${options.ssl_mode}`);
} Type guard
function isValidSslMode(m) { return ["disabled","preferred","required"].includes(String(m).toLowerCase()); } Try / catch
try { await createCdcTable({...options, ssl_mode: 'required'}); } catch (e) { if (String(e).includes('unsupported SSL mode')) { /* fix ssl_mode and retry */ } else throw e; } Prevention
- Only use ssl_mode values documented for mysql-cdc: disabled/preferred/required
- Never copy Postgres ssl_mode values into MySQL CDC options
- Validate the WITH clause options against the connector docs before DDL
When it happens
Trigger: Creating a CDC table with WITH ssl_mode set to a value other than 'disabled', 'preferred', or 'required' (e.g. 'verify-ca', 'verify-full', 'true', or a misspelled variant).
Common situations: Copy-pasting Postgres-style ssl_mode values (verify-ca/verify-full) into a MySQL CDC connection; enabling TLS docs from another driver; typos like 'require' or case differences.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- missing required property 'port' for MySQL CDC source
- received a DDL message, please set `canal.instance.filter.qu
- no value found at column: {}, index: {}
- failed to deserialize MySQL value into rust value
- failed to deserialize MySQL value into rw value
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/e326ca88a2a8db69.
Report an issue: GitHub.