risingwavelabs/risingwave · error
MySQL table doesn't define the primary key
Error message
MySQL table doesn't define the primary key
What it means
When discovering the schema of a CDC source table, RisingWave requires a primary key to construct its internal column descriptors (pk_names). MySQL tables without a PRIMARY KEY (or usable unique index) cannot be tracked for CDC, so connect() aborts schema discovery with this error.
Source
Thrown at src/connector/src/source/cdc/external/mysql.rs:193
);
None
});
ColumnDesc::named_with_default_value(
col_name.clone(),
ColumnId::placeholder(),
data_type.clone(),
snapshot_value,
)
} else {
ColumnDesc::named(col_name.clone(), ColumnId::placeholder(), data_type)
};
column_descs.push(column_desc);
}
let pk_names = primary_key_names(&indexes)
.ok_or_else(|| anyhow!("MySQL table doesn't define the primary key"))?;
Ok(Self {
column_descs,
pk_names,
})
}
pub fn column_descs(&self) -> &Vec<ColumnDesc> {
&self.column_descs
}
pub fn pk_names(&self) -> &Vec<String> {
&self.pk_names
}
}
fn primary_key_names(indexes: &[IndexInfo]) -> Option<Vec<String>> {
indexes
.iter()View on GitHub (pinned to 6469eb736d)
Solutions
- Add a PRIMARY KEY to the MySQL source table (ALTER TABLE ... ADD PRIMARY KEY (...)).
- Create the RisingWave table on a different table that has a primary key.
- If no key can be added, CDC replication of that table is unsupported; pick another ingestion method.
Example fix
// before CREATE TABLE orders (...); -- no PK in MySQL // after ALTER TABLE orders ADD PRIMARY KEY (id);
Defensive patterns
Strategy: validation
Validate before calling
-- run on MySQL before creating the CDC table SELECT TABLE_NAME FROM information_schema.TABLES t WHERE t.TABLE_SCHEMA = 'mydb' AND t.TABLE_NAME = 'orders' AND EXISTS (SELECT 1 FROM information_schema.TABLE_CONSTRAINTS c WHERE c.TABLE_SCHEMA = t.TABLE_SCHEMA AND c.TABLE_NAME = t.TABLE_NAME AND c.CONSTRAINT_TYPE = 'PRIMARY KEY');
Type guard
async function tableHasPrimaryKey(conn, schema, table) {
const rows = await conn.query(
"SELECT 1 FROM information_schema.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA=? AND TABLE_NAME=? AND CONSTRAINT_TYPE='PRIMARY KEY'", [schema, table]);
return rows.length > 0;
} Try / catch
try { await createCdcTable('orders'); } catch (e) { if (String(e).includes("doesn't define the primary key")) { await mysqlExec('ALTER TABLE orders ADD PRIMARY KEY (id)'); } else throw e; } Prevention
- Ensure every MySQL table targeted by CDC has an explicit PRIMARY KEY
- Check information_schema.TABLE_CONSTRAINTS before onboarding tables
- Do not rely on unique secondary indexes as a substitute for a PK
When it happens
Trigger: CREATE TABLE ... WITH (connector='mysql-cdc') referencing a MySQL table that has no PRIMARY KEY defined.
Common situations: Legacy tables created without keys; views or tables relying on unique secondary indexes only; developer assumed a unique index is enough.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Postgres table should define the primary key for non-append-
- Debezium Mongo needs a `_id` column in table
- {connector_name} snapshot primary-key index {index} is out o
- {connector_name} snapshot primary key `{}` cannot be NULL
- unsupported data type: {}, set to null
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/6fead95d63757440.
Report an issue: GitHub.