{"record":{"id":"ed92edcc9cdc365f","repo":"risingwavelabs/risingwave","slug":"postgresql-table-exists-but-the-connection-use","errorCode":null,"errorMessage":"PostgreSQL table {} exists, but the connection user `{}` does not have USAGE privilege on schema `{}`. Grant privileges on the upstream PostgreSQL database: {}","messagePattern":"PostgreSQL table (.+?) exists, but the connection user `(.+?)` does not have USAGE privilege on schema `(.+?)`\\. Grant privileges on the upstream PostgreSQL database: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/connector/src/connector_common/postgres.rs","lineNumber":347,"sourceCode":"        let privilege_status = PostgresTablePrivilege {\n            user_name: row.get(\"user_name\"),\n            schema_exists: row.get(\"schema_exists\"),\n            table_exists: row.get(\"table_exists\"),\n            has_schema_usage: row.get(\"has_schema_usage\"),\n            has_table_privilege: row.get(\"has_table_privilege\"),\n            has_any_column_privilege: row.get(\"has_any_column_privilege\"),\n        };\n\n        if !privilege_status.schema_exists {\n            return Err(anyhow!(\"PostgreSQL schema `{schema}` does not exist\").into());\n        }\n\n        if !privilege_status.table_exists {\n            return Err(anyhow!(\"PostgreSQL table `{schema}`.`{table}` does not exist\").into());\n        }\n\n        if !privilege_status.has_schema_usage {\n            return Err(anyhow!(\n                \"PostgreSQL table {} exists, but the connection user `{}` does not have USAGE privilege on schema `{}`. Grant privileges on the upstream PostgreSQL database: {}\",\n                format_pg_table_name(schema, table),\n                privilege_status.user_name,\n                schema,\n                format_grant_usage(schema, &privilege_status.user_name),\n            )\n            .into());\n        }\n\n        if !privilege_status.has_table_privilege {\n            let column_privilege_msg = if privilege_status.has_any_column_privilege {\n                \" The user has column-level privilege on at least one column, but RisingWave requires table-level privilege for CDC schema discovery and snapshot reads.\"\n            } else {\n                \"\"\n            };\n            return Err(anyhow!(\n                \"PostgreSQL table {} exists, but the connection user `{}` does not have {} privilege on it.{} Grant privileges on the upstream PostgreSQL database: {}\",\n                format_pg_table_name(schema, table),","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/connector_common/postgres.rs#L329-L365","documentation":"After confirming schema and table exist, ensure_table_privilege verifies the connection user holds the USAGE privilege on the schema (needed to resolve and read objects within it). This error is raised when the user lacks that privilege, and the message includes a ready-made GRANT statement to fix it.","triggerScenarios":"Creating a PostgreSQL CDC/table source where the configured user passes existence checks but has never been granted `USAGE ON SCHEMA <schema>`, e.g. a fresh replication/readonly user provisioned only with table-level grants.","commonSituations":"Newly created users in hardened Postgres setups where public schema USAGE was revoked; users restricted to a single database; DBAs granting SELECT on tables but forgetting schema USAGE; schema owners using non-public schemas.","solutions":["Run the GRANT printed in the error message: `GRANT USAGE ON SCHEMA <schema> TO <user>;` as a superuser or schema owner.","Also grant table read privileges needed by the source (e.g. `GRANT SELECT ON <schema>.<table> TO <user>;`).","For CDC, additionally verify replication prerequisites: REPLICATION role/`pg_hba.conf` entry and a publication covering the table.","Re-run source creation after the grants take effect (no server restart needed)."],"exampleFix":"// before: user has SELECT but no schema USAGE\n// after: grant USAGE on the schema\nGRANT USAGE ON SCHEMA app TO rw_user;\nGRANT SELECT ON app.orders TO rw_user;","handlingStrategy":"validation","validationCode":"// verify USAGE privilege before creating the source\nSELECT has_schema_privilege('rw_user', 'app', 'USAGE');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Provision connector users with GRANT USAGE ON SCHEMA plus table SELECT","Run has_schema_privilege checks in deployment runbooks","For CDC, also pre-verify REPLICATION role, pg_hba.conf, and publication coverage"],"tags":["postgresql","cdc","permissions","grants"],"backgroundTag":"insufficient-permissions","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}