hasura/graphql-engine · error · Error
HTTP method {0} not supported
Error message
HTTP method {0} not supported What it means
The pre-route hook returned a routing instruction whose HTTP method string is not supported by the executor — the {0} field contains the rejected method name. Only a known set of methods can be applied to the rewritten/routed request.
Source
Thrown at v3/crates/plugins/pre-route-plugin/src/execute.rs:32
};
use serde_json::json;
use tracing_util::{
ErrorVisibility, SpanVisibility, Traceable, TraceableError, set_attribute_on_active_span,
};
#[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),
#[error("HTTP method {0} not supported")]
UnsupportedHTTPMethod(String),
#[error("Invalid header name {0}")]
InvalidHeaderName(String),
#[error("Invalid header value {0}")]
InvalidHeaderValue(String),
#[error("Not found")]
NotFound,
// Only used in the pre-route plugin handler function. Defined to ensure consistent
// response formatting in IntoResponse impl.
#[error("Cannot load pre-route plugins: {0}")]
CannotLoadPlugins(String),
}
impl TraceableError for Error {
fn visibility(&self) -> ErrorVisibility {
ErrorVisibility::Internal
}
}View on GitHub (pinned to 724551b9ae)
Solutions
- Fix the hook to only return methods the engine supports (GET, POST, PUT, DELETE, HEAD, OPTIONS as documented).
- Normalize the method string (trim, uppercase) before returning it from the hook.
- Upgrade the engine crate if a newer version added support for the method you need.
Example fix
// before (hook)
{"method": method_from_client} // may be "patch" or custom
// after (hook)
let m = method_from_client.trim().to_uppercase();
assert!(matches!(m.as_str(), "GET"|"POST"|"PUT"|"DELETE"|"HEAD"|"OPTIONS"));
{"method": m} Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED: &[&str] = &["GET","POST","PUT","DELETE","HEAD","OPTIONS"];
fn supported_method(m: &str) -> bool { SUPPORTED.contains(&m.trim().to_uppercase().as_str()) } Type guard
fn is_supported_method(m: &str) -> bool {
matches!(m.trim().to_uppercase().as_str(), "GET"|"POST"|"PUT"|"DELETE"|"HEAD"|"OPTIONS")
} Try / catch
if let Error::UnsupportedHTTPMethod(m) = &e { tracing::warn!("hook sent unsupported method {m}; keeping original"); } Prevention
- Normalize and allowlist methods in hook code before returning instructions.
- Add unit tests for method handling in the hook.
- Upgrade the engine crate when new method support is required.
When it happens
Trigger: The hook responds with an instruction to rewrite the request using a method like "PATCH", "TRACE", or a custom string that the executor's match does not handle.
Common situations: Hook written to forward arbitrary client methods; typo'd method name ("GET " with whitespace, lowercase mismatch); newer method support added to the hook but not the engine crate version in use.
Related errors
- 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}
- Invalid header name {0}
- Error parsing the request: {0}
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/2f191599cef5b2e5.
Report an issue: GitHub.