hasura/graphql-engine · error · Error

User error from plugin {plugin_name}

Error message

User error from plugin {plugin_name}

What it means

The pre-NDC-request plugin rejected the incoming request as invalid from the user's perspective — the payload failed the plugin's own validation rules. The engine surfaces the plugin name plus the plugin's JSON error detail so the client can be told what was wrong. Unlike PluginInternalError, this is a 4xx-style expected failure caused by the request itself.

Source

Thrown at v3/crates/plugins/pre-ndc-request-plugin/src/execute.rs:31

#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error("Error while making the HTTP request to the pre-parse plugin {0} - {1}")]
    ErrorWhileMakingHTTPRequestToTheHook(String, reqwest::Error),
    #[error("Error while building the request for the pre-parse plugin {0} - {1}")]
    BuildRequestError(String, #[source] BuildRequestError),
    #[error("Reqwest error: {0}")]
    ReqwestError(reqwest::Error),
    #[error("Unexpected status code: {0}")]
    UnexpectedStatusCode(u16),
    #[error("Error parsing the request: {0}")]
    PluginRequestParseError(serde_json::error::Error),
    #[error("Internal error from plugin {plugin_name}")]
    PluginInternalError {
        plugin_name: String,
        error: serde_json::Value,
    },
    #[error("User error from plugin {plugin_name}")]
    PluginUserError {
        plugin_name: String,
        error: serde_json::Value,
    },
}

#[derive(Debug, thiserror::Error)]
pub enum BuildRequestError {
    #[error("Invalid header name {header_name}: {error}")]
    InvalidHeaderName {
        header_name: String,
        #[source]
        error: InvalidHeaderName,
    },
    #[error("Invalid header value for header {header_name}: {error}")]
    InvalidHeaderValue {
        header_name: HeaderName,
        #[source]

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Read the error JSON — it states which part of the request the plugin rejected
  2. Fix the client request to satisfy the plugin's validation rule (header, argument, role, etc.)
  3. If the rejection is unexpected, check that the plugin's validation config matches the intended policy
  4. Disable or narrow the plugin rule temporarily in dev to confirm it is the source
Defensive patterns

Strategy: try-catch

Try / catch

match result {
    Err(Error::PluginUserError { plugin_name, error }) => {
        // map to a 4xx for the client with the plugin's detail
    }
    other => other,
}

Prevention

When it happens

Trigger: The plugin hook responds with a user-error body (HTTP 400-ish) and the executor maps it to Error::PluginUserError { plugin_name, error }.

Common situations: A request validation plugin rejecting queries with missing headers, forbidden arguments, or auth claims that fail policy checks; role/permission enforcement hooks denying access.

Related errors


AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28). Data as JSON: /api/errors/477e054012f9b5f2. Report an issue: GitHub.