nautechsystems/nautilus_trader · error

Failed to parse debug_traceTransaction response

Error message

Failed to parse debug_traceTransaction response

What it means

This error is thrown when the raw HTTP body returned for a `debug_traceTransaction` JSON-RPC call cannot be deserialized into the expected `RpcNodeHttpResponse<serde_json::Value>` envelope. It means the node (or an intermediary proxy) returned a response body that is not well-formed JSON or not shaped like a JSON-RPC response. The library throws it inside `probe_call_trace` after the request itself succeeded at the transport level.

Source

Thrown at crates/adapters/blockchain/src/rpc/http.rs:831

                        "withLog": false,
                    },
                }
            ],
        });
        let bytes = self
            .send_rpc_request(request, Some(EXECUTION_RPC_TIMEOUT_SECS))
            .await
            .map_err(|e| match e {
                BlockchainRpcClientError::ClientError(message)
                    if message.contains("redirect response rejected") =>
                {
                    anyhow::anyhow!("debug_traceTransaction redirect rejected")
                }
                _ => anyhow::anyhow!("debug_traceTransaction request failed"),
            })?;
        let parsed =
            serde_json::from_slice::<RpcNodeHttpResponse<serde_json::Value>>(bytes.as_ref())
                .map_err(|_| anyhow::anyhow!("Failed to parse debug_traceTransaction response"))?;
        if parsed.jsonrpc.is_none()
            && let (Some(code), Some(_)) = (parsed.code, parsed.message)
        {
            return trace_probe_result(code);
        }

        if let Some(error) = parsed.error {
            return trace_probe_result(error.code);
        }
        anyhow::ensure!(
            parsed.result.is_some(),
            "debug_traceTransaction returned no result"
        );
        Ok(())
    }

    /// Broadcasts a signed raw transaction via `eth_sendRawTransaction`.
    ///

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Curl the endpoint's debug_traceTransaction directly and inspect the raw body for HTML/proxy error pages.
  2. Point the execution endpoint at a node with the debug API enabled (e.g. geth --http.api debug,erigon) rather than a proxy that strips or fails it.
  3. Reduce trace scope (fewer blocks / simpler call) if body size limits at the proxy are truncating the response.
  4. Retry, or switch to a fallback RPC provider if the node is intermittently returning malformed bodies.

Example fix

// before
let url = "http://proxy.example.com/v1"; // proxy returns HTML on trace APIs
// after
let url = "https://geth-node.internal:8545"; // direct node with debug API enabled
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check: ensure endpoint returns JSON, not HTML
let head = reqwest::Client::new().post(endpoint)
    .json(&serde_json::json!({"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}))
    .send().await?;
let ct = head.headers().get(reqwest::header::CONTENT_TYPE).and_then(|v| v.to_str().ok()).unwrap_or("");
if !ct.contains("json") { return Err(anyhow!("endpoint does not return JSON: content-type={ct}")); }

Type guard

fn looks_like_json_rpc_response(body: &[u8]) -> bool {
    serde_json::from_slice::<serde_json::Value>(body)
        .map(|v| v.get("jsonrpc").is_some() || v.get("result").is_some() || v.get("error").is_some())
        .unwrap_or(false)
}

Try / catch

match probe_call_trace(tx_hash) {
    Err(e) if e.to_string().contains("Failed to parse debug_traceTransaction response") => {
        tracing::warn!(%tx_hash, "malformed trace response; falling back to alternate node");
        fallback_node.probe_call_trace(tx_hash)
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling `probe_call_trace` against an execution endpoint whose `debug_traceTransaction` reply is not a valid JSON-RPC response object (missing/invalid JSON structure), e.g. an HTML error page, truncated body, or a proxy/CORS interstitial, so `serde_json::from_slice::<RpcNodeHttpResponse<Value>>` fails.

Common situations: Node behind a reverse proxy (nginx/Cloudflare) that intercepts the request and returns HTML; tracing module (`debug_*` namespace) handled by a different upstream than expected; load balancer returning 502/504 HTML bodies; extremely large traces causing gateway body truncation or timeouts.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/2d559079c50e9b01. Report an issue: GitHub.