hasura/graphql-engine · error · Error
Unexpected status code: {0}
Error message
Unexpected status code: {0} What it means
The pre-parse plugin executor received an HTTP response from the hook with a status code it does not recognize as success or as the special continue-signal (299). Any status outside the accepted set is surfaced with its numeric code.
Source
Thrown at v3/crates/plugins/pre-parse-plugin/src/execute.rs:31
use tracing_util::{
ErrorVisibility, SpanVisibility, Traceable, TraceableError, set_attribute_on_active_span,
};
/// HTTP status code used by pre-parse plugins to indicate they want to continue
/// processing with a modified request body.
///
/// We use 299 (an unassigned 2xx status code) as a special signal for this.
const CONTINUE_WITH_REQUEST_STATUS: u16 = 299;
#[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, String),
#[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),
}
impl Error {
pub fn is_internal(&self) -> bool {
match self {
Error::ErrorWhileMakingHTTPRequestToTheHook(_, _) | Error::UnexpectedStatusCode(_) => {
false
}
Error::BuildRequestError(_, _)
| Error::ReqwestError(_)
| Error::PluginRequestParseError(_) => true,
}
}
pub fn into_graphql_error(self) -> lang_graphql::http::GraphQLError {View on GitHub (pinned to 724551b9ae)
Solutions
- Check the plugin service logs to see why it returned that status.
- Fix contract mismatches: confirm the hook's expected payload/response shape matches the engine's plugin version.
- Align auth credentials/tokens between engine and plugin if the status is 401/403.
- Upgrade engine and plugin crates together so the status-code contract (including 299 continue) matches.
Defensive patterns
Strategy: try-catch
Try / catch
if let Error::UnexpectedStatusCode(code) = &e {
tracing::error!("hook returned {code}");
// decide: fail open (continue without plugin) vs fail closed
} Prevention
- Contract-test the hook's status codes (including the 299 continue signal) in CI.
- Return only documented statuses from hook implementations.
- Version-pin engine and plugin together.
When it happens
Trigger: The hook returns 4xx/5xx or any unexpected status; e.g. the plugin returns 400 for a malformed hook payload, or 500 because the plugin itself errored while processing the request.
Common situations: Plugin version mismatch changing the expected contract; plugin returning an auth error (401/403) because shared secrets differ; plugin bug returning 500.
Related errors
- Unexpected status code: {0}
- Error while making the HTTP request to the pre-parse plugin
- Error while building the request for the pre-parse plugin {0
- Unexpected status code: {0}
- Unexpected status code: {0}
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/3cd12074eef8177a.
Report an issue: GitHub.