{"record":{"id":"1977a8ecd02d15fa","repo":"risingwavelabs/risingwave","slug":"sql-server-table-permission-metadata-error","errorCode":null,"errorMessage":"SQL Server table {} permission metadata error","messagePattern":"SQL Server table (.+?) permission metadata error","errorType":"validation","errorClass":"SinkError::SqlServer","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/sqlserver.rs","lineNumber":660,"sourceCode":"        else {\n            return Err(query_table_metadata_error());\n        };\n        sql_server_table_metadata.push(SqlServerColumnMetadata {\n            name: normalize_sql_server_column_name(&col_name),\n            is_pk: col_is_pk != 0,\n            data_type: data_type.into_owned(),\n        });\n    }\n    Ok(sql_server_table_metadata)\n}\n\nasync fn validate_sql_server_write_permission(\n    sql_client: &mut SqlServerClient,\n    config: &SqlServerConfig,\n    is_append_only: bool,\n) -> Result<()> {\n    let permission_query_error = || {\n        SinkError::SqlServer(anyhow!(format!(\n            \"SQL Server table {} permission metadata error\",\n            config.full_object_path()\n        )))\n    };\n    static QUERY_WRITE_PERMISSION: &str = r#\"\nSELECT\n    CAST(HAS_PERMS_BY_NAME(@P1, 'OBJECT', 'INSERT') AS int) AS CanInsert,\n    CAST(HAS_PERMS_BY_NAME(@P1, 'OBJECT', 'UPDATE') AS int) AS CanUpdate,\n    CAST(HAS_PERMS_BY_NAME(@P1, 'OBJECT', 'DELETE') AS int) AS CanDelete;\"#;\n    let rows = sql_client\n        .inner_client\n        .query(QUERY_WRITE_PERMISSION, &[&config.full_object_path()])\n        .await?\n        .into_results()\n        .await?;\n    let mut rows = rows.into_iter().flatten();\n    let row = rows.next().ok_or_else(permission_query_error)?;\n    let mut iter = row.into_iter();","sourceCodeStart":642,"sourceCodeEnd":678,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/sqlserver.rs#L642-L678","documentation":"When validating that the configured SQL Server user may write to the sink table, RisingWave runs a permission-discovery query (SELECT/INSERT/UPDATE/DELETE grants). Any failure executing that permission query is wrapped in this error, again naming the table via `full_object_path()`. This is distinct from error 892: here the query itself failed; the permission result was never evaluated.","triggerScenarios":"`validate` -> `validate_sql_server_write_permission` runs its permission-check SQL and the client returns Err: connection failure, malformed query result, insufficient rights to read permission metadata, or driver error.","commonSituations":"User has rights on the table but cannot query `sys.database_permissions`/`fn_my_permissions`; server restart or transient network drop during sink validation; wrong database in URL so permission views don't exist; restricted login (contained user without VIEW DEFINITION).","solutions":["Grant the sink user permission-metadata read access: `GRANT VIEW DEFINITION TO <user>;` in the target database.","Confirm connectivity and correct database in the SQL Server URL before creating the sink.","Manually run the permission query (`SELECT * FROM fn_my_permissions('<schema>.<table>', 'OBJECT')`) as the sink user to see the raw error.","Check RisingWave logs for the wrapped driver error to distinguish auth vs network causes."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"-- run as the sink user\nSELECT * FROM fn_my_permissions('dbo.orders', 'OBJECT');","typeGuard":null,"tryCatchPattern":"// wrap sink validation and classify permission-query failures\nif let Err(e) = sink.validate().await {\n    if e.to_string().contains(\"permission metadata error\") {\n        log::warn!(\"cannot read permissions: check VIEW DEFINITION grant\");\n    }\n    return Err(e);\n}","preventionTips":["Grant VIEW DEFINITION to the sink principal at setup time","Validate credentials with sqlcmd before sink creation","Keep the target database consistent between URL and grants"],"tags":["sqlserver","sink","permissions","metadata-query"],"backgroundTag":"database-query-failed","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"}