risingwavelabs/risingwave · critical
No result returned by `SELECT sys.fn_cdc_get_max_lsn()`
Error message
No result returned by `SELECT sys.fn_cdc_get_max_lsn()`
What it means
`current_cdc_offset` queries `SELECT sys.fn_cdc_get_max_lsn()` to obtain the current maximum LSN as the starting CDC offset. It panics via `.expect` if the query yields no row at all — meaning the CDC metadata function returned nothing, which indicates CDC is not enabled or the database is unreachable/misconfigured.
Source
Thrown at src/connector/src/source/cdc/external/sql_server.rs:234
#[derive(Debug)]
pub struct SqlServerExternalTableReader {
rw_schema: Schema,
pk_indices: Vec<usize>,
field_names: String,
client: tokio::sync::Mutex<SqlServerClient>,
}
impl ExternalTableReader for SqlServerExternalTableReader {
async fn current_cdc_offset(&self) -> ConnectorResult<CdcOffset> {
let mut client = self.client.lock().await;
// start a transaction to read max start_lsn.
let row = client
.inner_client
.simple_query(String::from("SELECT sys.fn_cdc_get_max_lsn()"))
.await?
.into_row()
.await?
.expect("No result returned by `SELECT sys.fn_cdc_get_max_lsn()`");
// An example of change_lsn or commit_lsn: "00000027:00000ac0:0002" from debezium
// sys.fn_cdc_get_max_lsn() returns a 10 bytes array, we convert it to a hex string here.
let max_lsn = match row.try_get::<&[u8], usize>(0)? {
Some(bytes) => {
let mut hex_string = String::with_capacity(bytes.len() * 2 + 2);
assert_eq!(
bytes.len(),
10,
"sys.fn_cdc_get_max_lsn() should return a 10 bytes array."
);
for byte in &bytes[0..4] {
hex_string.push_str(&format!("{:02x}", byte));
}
hex_string.push(':');
for byte in &bytes[4..8] {
hex_string.push_str(&format!("{:02x}", byte));
}
hex_string.push(':');View on GitHub (pinned to 6469eb736d)
Solutions
- Enable CDC on the database and table: `EXEC sys.sp_cdc_enable_db;` then `EXEC sys.sp_cdc_enable_table ...`.
- Grant the connecting login sufficient privileges (db_owner or membership allowing fn_cdc_get_max_lsn).
- Verify connectivity and that the endpoint really is SQL Server (correct host/port/database).
- If the panic is unacceptable in your deployment, patch the code to return a ConnectorResult error instead of `expect`.
Example fix
// before
.expect("No result returned by `SELECT sys.fn_cdc_get_max_lsn()`");
// after
.ok_or_else(|| anyhow!("No result returned by `SELECT sys.fn_cdc_get_max_lsn()`; ensure CDC is enabled"))? Defensive patterns
Strategy: validation
Validate before calling
-- Run before creating the source; must return one row with a non-NULL 10-byte value: SELECT sys.fn_cdc_get_max_lsn(); SELECT name, is_cdc_enabled FROM sys.databases WHERE database_id = DB_ID(); SELECT name FROM sys.tables WHERE is_tracked_by_cdc = 1;
Try / catch
match client.simple_query("SELECT sys.fn_cdc_get_max_lsn()").await {
Ok(v) => v,
Err(e) => return Err(e.into()),
} // and treat an empty/NULL result as a config error, not a panic Prevention
- Always enable CDC at DB and table level (sp_cdc_enable_db, sp_cdc_enable_table) first.
- Connect with a login that has db_owner or higher.
- Keep SQL Server Agent running so the capture job maintains LSNs.
When it happens
Trigger: Starting/resuming a SQL Server CDC source when the query returns zero rows: CDC not enabled on the database/table, missing db_owner/sysadmin privileges for fn_cdc_get_max_lsn, or connecting to a non-SQL-Server endpoint.
Common situations: Forgot to run `EXEC sys.sp_cdc_enable_db` / `sp_cdc_enable_table`; connecting with a low-privilege login; Azure SQL database without CDC enabled; wrong port pointing to another service.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- SQL Server LSN should be 10 bytes, got {} bytes
- SQL Server max_lsn is NULL
- SQL Server min_lsn is NULL
- None is returned by `SELECT sys.fn_cdc_get_max_lsn()`, pleas
- conversion of SQL Server money to {data_type} is not support
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/5eb43b4333153834.
Report an issue: GitHub.