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-response plugin flagged the response as failing a user-facing rule (a validation/policy check on the outgoing response). The plugin name and its JSON error detail are surfaced so the caller knows which rule rejected the response. This is an expected 4xx-class outcome, not a plugin bug.

Source

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

#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error("Error while making the HTTP request to the pre-response plugin {0} - {1}")]
    ErrorWhileMakingHTTPRequestToTheHook(String, reqwest::Error),
    #[error("Error while building the request for the pre-response 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 detail to see which policy/rule triggered
  2. Adjust the query (fields selected, filters) to comply with the plugin's rule
  3. If the rule is too strict, update the plugin's policy configuration
  4. Verify the rule change history — a config tightening often explains sudden failures
Defensive patterns

Strategy: try-catch

Try / catch

if let Err(Error::PluginUserError { plugin_name, error }) = res {
    // return 4xx to client with the plugin's detail
}

Prevention

When it happens

Trigger: The hook inspects the outgoing NDC response and returns a user-error body, e.g. a data-redaction or row-limit policy finding forbidden fields, and the engine maps it to PluginUserError.

Common situations: Response-filtering plugins rejecting rows containing secret columns; row-count limit policies; plugins whose rules were tightened and now reject previously-allowed responses.

Related errors


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