risingwavelabs/risingwave · error · SinkError::SqlServer
SQL Server user {} lacks required write permission(s) {} on
Error message
SQL Server user {} lacks required write permission(s) {} on table {} What it means
After evaluating the permission query, RisingWave compares the grants it found (can_select/insert/update/delete as required by append-only vs upsert mode) against what is needed. If any required permission is missing it throws this error listing the user, the missing permission names joined by commas, and the target table. It is a deliberate preflight check so sinks fail fast instead of erroring mid-stream on write.
Source
Thrown at src/connector/src/sink/sqlserver.rs:699
};
let ColumnData::I32(can_update) = iter.next().ok_or_else(permission_query_error)? else {
return Err(permission_query_error());
};
let ColumnData::I32(can_delete) = iter.next().ok_or_else(permission_query_error)? else {
return Err(permission_query_error());
};
let missing_permissions = missing_sql_server_write_permissions(
is_append_only,
permission_is_granted(can_insert),
permission_is_granted(can_update),
permission_is_granted(can_delete),
);
if missing_permissions.is_empty() {
return Ok(());
}
Err(SinkError::SqlServer(anyhow!(format!(
"SQL Server user {} lacks required write permission(s) {} on table {}",
config.user,
missing_permissions.join(", "),
config.full_object_path()
))))
}
fn permission_is_granted(permission_value: Option<i32>) -> bool {
permission_value == Some(1)
}
fn missing_sql_server_write_permissions(
is_append_only: bool,
can_insert: bool,
can_update: bool,
can_delete: bool,
) -> Vec<&'static str> {
let mut missing_permissions = vec![];View on GitHub (pinned to 6469eb736d)
Solutions
- Grant the missing permissions in SQL Server: e.g. `GRANT INSERT, UPDATE, DELETE ON <schema>.<table> TO <user>;` (match what the error lists).
- Ensure the user in the sink config is the same principal you granted permissions to (check for login vs user mismatch).
- Check for explicit DENY entries overriding grants: `SELECT * FROM sys.database_permissions WHERE grantee_principal_id = USER_ID('<user>')`.
- If the sink is append-only, INSERT alone suffices; alternatively switch sink mode to match the permissions actually granted.
Example fix
-- before: user has only SELECT GRANT SELECT ON dbo.orders TO rw_sink; -- after: grant writes required by an upsert sink GRANT SELECT, INSERT, UPDATE, DELETE ON dbo.orders TO rw_sink;
Defensive patterns
Strategy: validation
Validate before calling
-- preflight: list granted permissions for the sink user
SELECT permission_name FROM fn_my_permissions('dbo.orders', 'OBJECT')
WHERE permission_name IN ('SELECT','INSERT','UPDATE','DELETE'); Try / catch
match sink.validate().await {
Err(e) if e.to_string().contains("lacks required write permission") => {
request_grants_from_dba(&parse_missing_permissions(&e.to_string()));
}
other => other,
} Prevention
- Grant SELECT+INSERT (+UPDATE+DELETE for upsert sinks) at provisioning time
- Confirm login/user principal name matches the sink config user exactly
- Check for DENY overrides when grants seem correct
- Automate permission checks in deployment scripts before CREATE SINK
When it happens
Trigger: `validate` -> `validate_sql_server_write_permission`: the query result shows the configured `config.user` lacks one or more of INSERT/UPDATE/DELETE (and SELECT for upsert) on the table. E.g. an append-only sink without INSERT, or an upsert sink missing UPDATE/DELETE.
Common situations: DBA granted permissions to a different login than the one in the sink config; role membership not applied; table owner changed; permissions granted only at schema level with DENY overrides; user created without login mapping.
Understand the failure class
Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.
Related errors
- SQL Server table {} permission metadata error
- {e}
- `{}` must be {}, or {}
- too many column {}
- Primary key not defined for upsert SQL Server sink (please d
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/9ea83bed166be88a.
Report an issue: GitHub.