FuelLabs/fuel-core · error · CynicReqwestError::ErrorResponse

{error}

Error message

{error}

What it means

In run_fuel_graphql's response handling (crates/client/src/reqwest_ext.rs:193-210), a non-2xx HTTP status triggers body-text capture; if that body is not valid JSON (i.e. not a GraphQL error payload), it is wrapped as CynicReqwestError::ErrorResponse(status, text) and surfaced as an anyhow error via '{error}'. This message therefore means: the server answered with an HTTP error status whose body was not a GraphQL response — typically an HTML or plain-text error page from a proxy, gateway, or the wrong endpoint.

Source

Thrown at crates/client/src/reqwest_ext.rs:203

    ResponseData: serde::de::DeserializeOwned + Send + 'static,
    ErrorExtensions: serde::de::DeserializeOwned + Send + 'static,
{
    let response = match response {
        Ok(response) => response,
        Err(e) => return Err(anyhow::anyhow!("{e}")),
    };

    let status = response.status();
    if !status.is_success() {
        let text = response.text().await;
        let text = match text {
            Ok(text) => text,
            Err(e) => return Err(anyhow::anyhow!("{e}")),
        };

        let Ok(deserred) = serde_json::from_str(&text) else {
            let error = CynicReqwestError::ErrorResponse(status, text);
            return Err(anyhow::anyhow!("{error}"));
        };

        Ok(deserred)
    } else {
        let json = response.json().await;
        json.map_err(|e| anyhow::anyhow!("{e}"))
    }
}

impl ReqwestExt for reqwest::RequestBuilder {
    fn run_fuel_graphql<ResponseData, Vars>(
        self,
        operation: FuelOperation<Operation<ResponseData, Vars>>,
    ) -> CynicReqwestBuilder<ResponseData>
    where
        Vars: serde::Serialize,
        ResponseData: serde::de::DeserializeOwned + 'static,
    {

View on GitHub (pinned to b9d4d170da)

Solutions

  1. Point the client at the node's GraphQL endpoint (e.g. http://127.0.0.1:4000/v1/graphql) and verify with curl -X POST.
  2. If the embedded status is 502/503/504, treat it as transient: retry with backoff or fail over to another URL via FuelClient::with_urls.
  3. Read the body text embedded in the error — it usually identifies the proxy, gateway, or failure reason.
  4. If behind a gateway, ensure it forwards GraphQL POST bodies and does not rewrite or intercept responses.

Example fix

// before
let resp = req.post(url).run_fuel_graphql(op).await?; // anyhow('{error}') on HTML 502

// after
let resp = match req.post(url).run_fuel_graphql(op).await {
    Ok(resp) => resp,
    Err(e) if ["500", "502", "503", "504"].iter().any(|s| e.to_string().contains(s)) => {
        // gateway/proxy-style failure: retry with backoff or switch endpoint
        retry_with_backoff(|| post_operation(&client, &op)).await?
    }
    Err(e) => return Err(e),
};
Defensive patterns

Strategy: try-catch

Try / catch

match req.post(url).run_fuel_graphql(op).await {
    Ok(resp) => resp,
    Err(e) if ["500", "502", "503", "504"].iter().any(|s| e.to_string().contains(s)) => {
        // proxy/gateway style failure: retry with backoff or fail over to the next URL
        retry_with_backoff(|| post_operation(&client, &op)).await?
    }
    Err(e) => return Err(e.context(format!("Fuel GraphQL request to {url} failed"))),
};

Prevention

When it happens

Trigger: Posting a Fuel GraphQL operation to a URL that returns 404/502/503/504 with an HTML or text body: missing /v1/graphql path or wrong port, reverse proxy failing while the node restarts, rate-limit page, or an auth gateway returning a login page.

Common situations: Wrong endpoint URL (path or port); node down with a load balancer serving an error page; gateway timeouts returning HTML; hitting a protected endpoint behind SSO/auth proxies.

Related errors


AI-assisted analysis of FuelLabs/fuel-core@b9d4d170da (2026-08-16). Data as JSON: /api/errors/dbe4ede7355a369f. Report an issue: GitHub.