nautechsystems/nautilus_trader · error

Failed to decode eth_getCode result: {e}

Error message

Failed to decode eth_getCode result: {e}

What it means

The `eth_getCode` result must be a hex-encoded bytecode string; after stripping an optional `0x` prefix, `hex::decode` is applied. Invalid hex characters or odd-length strings produce this error including the decode error `e`.

Source

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

        B256::from_str(&value)
            .map_err(|_| anyhow::anyhow!("Failed to parse eth_getStorageAt response"))
    }

    async fn get_code_with_block(
        &self,
        address: &Address,
        block: Option<u64>,
    ) -> anyhow::Result<Bytes> {
        let result: Option<String> = self
            .execute_execution_rpc_call(
                "eth_getCode",
                serde_json::json!([address, block_parameter(block)]),
            )
            .await?;
        let hex_string = result.ok_or_else(|| anyhow::anyhow!("eth_getCode returned no result"))?;
        let stripped = hex_string.strip_prefix("0x").unwrap_or(&hex_string);
        let bytes = hex::decode(stripped)
            .map_err(|e| anyhow::anyhow!("Failed to decode eth_getCode result: {e}"))?;
        Ok(Bytes::from(bytes))
    }

    /// Returns the next nonce for the given address via `eth_getTransactionCount`
    /// with the `pending` tag, making the pending pool state authoritative.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails or the result is missing or malformed.
    pub async fn get_transaction_count_pending(&self, address: &Address) -> anyhow::Result<u64> {
        let result: Option<String> = self
            .execute_execution_rpc_call(
                "eth_getTransactionCount",
                serde_json::json!([address, "pending"]),
            )
            .await?;
        parse_hex_quantity_result("eth_getTransactionCount", result)
            .and_then(|v| u64::try_from(v).map_err(Into::into))

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Log the raw hex_string to identify the invalid portion
  2. Verify endpoint integrity (no body-rewriting proxies) and retry against the node directly
  3. Fix upstream encoding — ensure 0x-prefixed, even-length hex
  4. Add a sanitize step (trim whitespace, strip 0x) if your node emits stray characters

Example fix

// before: failing on whitespace in response
let bytes = hex::decode(stripped)?;
// after: sanitize first
let cleaned: String = stripped.chars().filter(|c| c.is_ascii_hexdigit()).collect();
let bytes = hex::decode(&cleaned)?;
Defensive patterns

Strategy: validation

Validate before calling

fn is_hex_bytecode(s: &str) -> bool {
    let body = s.strip_prefix("0x").unwrap_or(s);
    body.len() % 2 == 0 && body.chars().all(|c| c.is_ascii_hexdigit())
}

Prevention

When it happens

Trigger: Node returns a code string that is not valid hex (corrupted response, non-hex encoding, odd number of hex digits, or embedded whitespace/HTML fragments).

Common situations: Proxy mangling the response body, a custom chain encoding code differently, or partial/truncated responses from an overloaded node.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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