risingwavelabs/risingwave · error · MetaError::PermissionDenied

{0}

Error message

{0}

What it means

MetaError::PermissionDenied carries a human-readable rejection message verbatim ('{0}'). It is thrown when an operation is not permitted — typically worker/privilege related checks in the meta service — and the message itself explains what was denied.

Source

Thrown at src/meta/src/error.rs:66

        #[backtrace]
        MetadataModelError,
    ),

    #[error("Hummock error: {0}")]
    HummockError(
        #[from]
        #[backtrace]
        HummockError,
    ),

    #[error(transparent)]
    RpcError(
        #[from]
        #[backtrace]
        RpcError,
    ),

    #[error("{0}")]
    PermissionDenied(String),

    #[error("Invalid worker: {0}, {1}")]
    InvalidWorker(WorkerId, String),

    #[error("Invalid parameter: {0}")]
    InvalidParameter(#[message] String),

    // Used for catalog errors.
    #[error("{0} id not found: {1}")]
    #[construct(skip)]
    CatalogIdNotFound(&'static str, String),

    #[error("table_fragment does not exist: id={0}")]
    FragmentNotFound(FragmentId),

    #[error("{0} named {1} already exists{under_creation}", under_creation = (.2).map(|_| " and is still being created").unwrap_or(""))]
    Duplicated(

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Read the message payload — it names the denied action/subject.
  2. Retry the operation with credentials/identity that have the required privileges.
  3. For SQL-level denials, GRANT the needed privileges to the role (e.g. GRANT ... TO ...).
  4. For worker registration issues, deregister and re-register the worker node.

Example fix

// before (non-superuser runs a restricted statement)
ALTER SYSTEM ...; -- PermissionDenied
// after
GRANT appropriate_role TO current_user;  -- or run as a privileged user
ALTER SYSTEM ...;
Defensive patterns

Strategy: try-catch

Validate before calling

-- Before running the operation, check privileges
SELECT has_privs_of(current_user, 'admin') AS can_alter_system;

Type guard

fn is_permission_denied(e: &MetaError) -> bool {
    matches!(e, MetaError::PermissionDenied(_))
}

Try / catch

match run_statement(sql).await {
    Err(e @ MetaError::PermissionDenied(msg)) => {
        // read `msg` to see exactly what was denied; elevate privileges or re-authenticate
        Err(anyhow!("denied: {msg}"))
    }
    other => other,
}

Prevention

When it happens

Trigger: A meta-service call whose permission check fails, e.g. a worker or user attempting an operation reserved for another role, producing `Err(MetaError::permission_denied(msg))`.

Common situations: Connecting a worker with wrong identity/registration state; RBAC-restricted SQL operations executed by a user lacking privileges against RisingWave's permission model; stale worker registrations after cluster re-provisioning.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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