risingwavelabs/risingwave · error · anyhow::Error

PostgreSQL table `{schema}`.`{table}` does not exist

Error message

PostgreSQL table `{schema}`.`{table}` does not exist

What it means

ensure_table_privilege checks upstream existence before privileges. This error is returned when the schema exists but the target table (`schema.table`) is not found on the upstream PostgreSQL database, so the connector refuses to proceed.

Source

Thrown at src/connector/src/connector_common/postgres.rs:343

            .fetch_one(connection)
            .await
            .context("Failed to check PostgreSQL table privileges")?;

        let privilege_status = PostgresTablePrivilege {
            user_name: row.get("user_name"),
            schema_exists: row.get("schema_exists"),
            table_exists: row.get("table_exists"),
            has_schema_usage: row.get("has_schema_usage"),
            has_table_privilege: row.get("has_table_privilege"),
            has_any_column_privilege: row.get("has_any_column_privilege"),
        };

        if !privilege_status.schema_exists {
            return Err(anyhow!("PostgreSQL schema `{schema}` does not exist").into());
        }

        if !privilege_status.table_exists {
            return Err(anyhow!("PostgreSQL table `{schema}`.`{table}` does not exist").into());
        }

        if !privilege_status.has_schema_usage {
            return Err(anyhow!(
                "PostgreSQL table {} exists, but the connection user `{}` does not have USAGE privilege on schema `{}`. Grant privileges on the upstream PostgreSQL database: {}",
                format_pg_table_name(schema, table),
                privilege_status.user_name,
                schema,
                format_grant_usage(schema, &privilege_status.user_name),
            )
            .into());
        }

        if !privilege_status.has_table_privilege {
            let column_privilege_msg = if privilege_status.has_any_column_privilege {
                " The user has column-level privilege on at least one column, but RisingWave requires table-level privilege for CDC schema discovery and snapshot reads."
            } else {
                ""

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Verify the table exists: `SELECT 1 FROM information_schema.tables WHERE table_schema='<schema>' AND table_name='<table>';`.
  2. Correct schema.name/table.name in the source options, matching exact case used at CREATE time.
  3. Confirm the connection string targets the database containing the table.
  4. If the table was renamed/dropped, recreate it or update the source config.

Example fix

// before
WITH (connector = 'postgres-cdc', schema.name = 'app', table.name = 'Orders')
// after: exact table name
WITH (connector = 'postgres-cdc', schema.name = 'app', table.name = 'orders')
Defensive patterns

Strategy: validation

Validate before calling

// check upstream table before creating the source
SELECT 1 FROM information_schema.tables
WHERE table_schema = 'public' AND table_name = 'orders';

Prevention

When it happens

Trigger: Creating a source/CDC table with `table.name` that does not exist in the given schema: typo in table name, table in a different schema, table dropped or renamed before source creation, wrong database in the connection config.

Common situations: Case-sensitive table names created with quotes but configured unquoted; table moved by a migration; pointing at a replica database without the table; schema/table swapped in the config fields.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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