linera-io/linera-protocol · error · EthereumQueryError

the ID should be matching

Error message

the ID should be matching

What it means

Raised by linera-ethereum's JsonRpcClient::request after deserializing a JSON-RPC response: the id in the response must equal the id the client generated for the request. JSON-RPC 2.0 requires responses to echo the request id so callers can match replies to requests; a mismatch means whatever answered is not correlating responses correctly (proxy rewriting ids, misrouted connection, or a non-conformant server).

Source

Thrown at linera-ethereum/src/client.rs:47

    async fn request_inner(&self, payload: Vec<u8>) -> Result<Vec<u8>, Self::Error>;

    /// Gets a new ID for the next message.
    async fn get_id(&self) -> u64;

    /// The function doing the parsing of the input and output.
    async fn request<T, R>(&self, method: &str, params: T) -> Result<R, Self::Error>
    where
        T: Debug + Serialize + Send + Sync,
        R: DeserializeOwned + Send,
    {
        let id = self.get_id().await;
        let payload = JsonRpcRequest::new(id, method, params);
        let payload = serde_json::to_vec(&payload)?;
        let body = self.request_inner(payload).await?;
        let result = serde_json::from_slice::<JsonRpcResponse>(&body)?;
        let raw = result.result;
        let res = serde_json::from_str(raw.get())?;
        ensure!(id == result.id, EthereumQueryError::IdIsNotMatching);
        ensure!(
            "2.0" == result.jsonrpc,
            EthereumQueryError::WrongJsonRpcVersion
        );
        Ok(res)
    }
}

#[derive(Serialize, Deserialize, Debug)]
struct JsonRpcRequest<'a, T> {
    id: u64,
    jsonrpc: &'a str,
    method: &'a str,
    params: T,
}

impl<'a, T> JsonRpcRequest<'a, T> {
    /// Creates a new JSON RPC request, the id does not matter

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Point the client directly at a conforming Ethereum node (reth/geth/besu) endpoint and retest
  2. Remove or fix the middleware in front of the node so it echoes request ids verbatim
  3. If you must use a gateway, verify with curl that a request with id 42 comes back with id 42
  4. Switch to a reputable hosted RPC provider known to be JSON-RPC 2.0 compliant

Example fix

// before
let client = EthereumClient::new("https://my-gateway.example/rpc"); // gateway rewrites ids

// after
let client = EthereumClient::new("http://eth-node.internal:8545"); // direct JSON-RPC 2.0 node
Defensive patterns

Strategy: validation

Validate before calling

// Smoke-test an endpoint before wiring it into the client: the response id must echo the request.
async fn endpoint_correlates_ids(url: &str) -> bool {
    let body = r#"{"jsonrpc":"2.0","id":424242,"method":"eth_blockNumber","params":[]}"#;
    let resp: serde_json::Value = reqwest::Client::new()
        .post(url)
        .header("content-type", "application/json")
        .body(body)
        .send().await.unwrap()
        .json().await.unwrap();
    resp.get("id") == Some(&serde_json::json!(424242))
}

Type guard

fn is_id_mismatch(err: &EthereumQueryError) -> bool {
    matches!(err, EthereumQueryError::IdIsNotMatching)
}

Try / catch

match client.get_balance(address).await {
    Err(e) if is_id_mismatch(&e) => {
        // The endpoint mangles request ids; switch to a direct node URL or another provider.
        Err(EthereumServiceError::EthereumQueryError(e))
    }
    other => other,
}

Prevention

When it happens

Trigger: Pointing the Ethereum client at an id-mangling middleware: naive load balancers, API gateways, or caching proxies that regenerate or drop the id; a WebSocket multiplexer delivering another request's response; a server that always answers with a fixed id (JSON-RPC 1.0 style). Hit from get_accounts, get_balance, is_block_hash_finalized.

Common situations: Using a corporate proxy or custom RPC gateway in front of the Ethereum node instead of the node itself; misconfigured dev/test mock servers; hosted RPC providers with non-standard front layers.

Related errors


AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22). Data as JSON: /api/errors/7b5dd4bb8ada4f17. Report an issue: GitHub.