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
- Read the error JSON — it states which part of the request the plugin rejected
- Fix the client request to satisfy the plugin's validation rule (header, argument, role, etc.)
- If the rejection is unexpected, check that the plugin's validation config matches the intended policy
- 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
- Document the plugin's validation rules for API consumers
- Validate requests client-side against the same rules where possible
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
- Error parsing the request: {0}
- Internal error from plugin {plugin_name}
- Error parsing the request: {0}
- Internal error from plugin {plugin_name}
- User error from plugin {plugin_name}
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/477e054012f9b5f2.
Report an issue: GitHub.