risingwavelabs/risingwave · error

invalid external table type

Error message

invalid external table type: {:?}

What it means

`ExternalCdcTableType::create_table_reader` only implements table readers for MySql, SqlServer, and Mock; citus is explicitly unsupported for CDC backfill. Any other variant (or citus) hits the catch-all `bail!` with this message naming the unexpected enum value. The caller is trying to initialize a parallel CDC table snapshot for a type that has no reader.

Solutions

  1. Use a supported CDC connector for the external table: 'mysql-cdc' or 'sqlserver-cdc'.
  2. If Citus backfill is needed, use a regular (non-CDC-backfill) approach or wait for support; citus is intentionally unsupported here.
  3. For developers: add a match arm wiring the new table type to its reader implementation.

Example fix

// before
WITH (connector = 'citus-cdc', ...)  -- bail: invalid external table type: Citus
// after
WITH (connector = 'mysql-cdc', hostname = '...', port = '3306', ...)
Defensive patterns

Strategy: validation

Validate before calling

let supported = ["mysql-cdc", "sqlserver-cdc"];
if !supported.contains(&connector.as_str()) {
    bail!("CDC backfill tables support only {:?}; got {}", supported, connector);
}

Try / catch

match ExternalCdcTableType::try_from(connector) {
    Ok(t @ (MySql | SqlServer)) => t.create_table_reader(...).await?,
    other => bail!("connector {:?} unsupported for CDC table backfill", other),
}

Prevention

When it happens

Trigger: try_init_parallel_cdc_table_snapshot_splits calls create_table_reader with an ExternalCdcTableType that is not MySql/SqlServer/Mock — typically Citus (CREATE TABLE with connector='citus-cdc') or any newly added connector variant lacking a reader arm.

Common situations: User attempts `CREATE TABLE ... WITH (connector = 'citus-cdc')` for CDC backfill, or a developer added a new ExternalCdcTableType variant without extending create_table_reader.

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.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/6bdfb7c709997339. Report an issue: GitHub.

Appendix: source

Thrown at src/connector/src/source/cdc/external/mod.rs:111

            Self::MySql => Ok(ExternalTableReaderImpl::MySql(
                MySqlExternalTableReader::new(config, schema, pk_indices).await?,
            )),
            Self::Postgres => Ok(ExternalTableReaderImpl::Postgres(
                PostgresExternalTableReader::new(
                    config,
                    schema,
                    pk_indices,
                    schema_table_name,
                    table_id,
                )
                .await?,
            )),
            Self::SqlServer => Ok(ExternalTableReaderImpl::SqlServer(
                SqlServerExternalTableReader::new(config, schema, pk_indices).await?,
            )),
            // citus is never supported for cdc backfill (create source + create table).
            Self::Mock => Ok(ExternalTableReaderImpl::Mock(MockExternalTableReader::new())),
            _ => bail!("invalid external table type: {:?}", *self),
        }
    }
}

impl From<ExternalCdcTableType> for PbCdcTableType {
    fn from(cdc_table_type: ExternalCdcTableType) -> Self {
        match cdc_table_type {
            ExternalCdcTableType::Postgres => Self::Postgres,
            ExternalCdcTableType::MySql => Self::Mysql,
            ExternalCdcTableType::SqlServer => Self::Sqlserver,

            ExternalCdcTableType::Citus => Self::Citus,
            ExternalCdcTableType::Mongo => Self::Mongo,
            ExternalCdcTableType::Undefined | ExternalCdcTableType::Mock => Self::Unspecified,
        }
    }
}

View on GitHub (pinned to 6469eb736d)