linera-io/linera-protocol · error · NodeError

The received chain info response is invalid

Error message

The received chain info response is invalid

What it means

Raised by RemoteNode::check_and_return_info, which validates every ChainInfoResponse coming back from a validator in handle_chain_info_query, handle_block_proposal, handle_timeout_certificate, handle_confirmed_certificate, handle_validated_certificate and handle_lite_certificate. The response is rejected unless the requested proposed block and requested locking certificate belong to the queried chain and response.check(validator_public_key) passes (signature verification against that validator's key). Failure means the validator's answer is malformed, unrelated to the requested chain, or not properly signed by the key we configured.

Source

Thrown at linera-core/src/remote_node.rs:161

                    certificate_hash = %certificate.hash(),
                    kind = ?C::Value::KIND,
                    "validator forgot a certificate value that they signed before",
                );
                None
            }
            other => Some(other),
        }
    }

    fn check_and_return_info(
        &self,
        response: ChainInfoResponse,
        chain_id: ChainId,
    ) -> Result<Box<ChainInfo>, NodeError> {
        let manager = &response.info.manager;
        let proposed = manager.requested_proposed.as_ref();
        let locking = manager.requested_locking.as_ref();
        ensure!(
            proposed.is_none_or(|proposal| proposal.content.block.chain_id == chain_id)
                && locking.is_none_or(|cert| cert.chain_id() == chain_id)
                && response.check(self.public_key).is_ok(),
            NodeError::InvalidChainInfoResponse
        );
        Ok(response.info)
    }

    #[instrument(level = "trace")]
    pub(crate) async fn download_certificate_for_blob(
        &self,
        blob_id: BlobId,
    ) -> Result<ConfirmedBlockCertificate, NodeError> {
        let certificate = self.node.blob_last_used_by_certificate(blob_id).await?;
        if !certificate.block().requires_or_creates_blob(&blob_id) {
            info!(
                address = self.address(),
                %blob_id,

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Verify the wallet's validator list: addresses and public keys must match the current committee
  2. Retry against a different validator (or let quorum aggregation skip the faulty one) and confirm the error is isolated to one node
  3. If behind a proxy, bypass it temporarily to check whether it corrupts responses
  4. Take the misbehaving validator out of rotation and report it
Defensive patterns

Strategy: fallback

Validate before calling

// Before relying on a validator, verify its advertised info is signed correctly for the chain you track.
let response = validator_node.handle_chain_info_query(chain_info_query_for(chain_id)).await?;
assert!(response.check(&validator_public_key).is_ok(), "validator key/response mismatch");

Type guard

fn is_invalid_chain_info_response(err: &NodeError) -> bool {
    matches!(err, NodeError::InvalidChainInfoResponse)
}

Try / catch

let results = futures::future::join_all(validators.iter().map(|node| async {
    node.handle_chain_info_query(query.clone()).await
}));
// Quorum pattern: proceed with the answers that verify; ignore InvalidChainInfoResponse ones
// as long as enough valid responses remain.

Prevention

When it happens

Trigger: Validator (or a proxy in front of it) returns chain info for a different chain_id in requested_proposed/requested_locking; response signature does not verify against the public key in the wallet's validator config; a misconfigured load balancer routing requests to the wrong backend; a byzantine validator fabricating responses.

Common situations: Wrong validator public key in the wallet (typo, stale committee after rotation); an nginx/gRPC proxy rewriting or replaying responses; hybrid test setups mixing mainnet and devnet keys. A single faulty validator is tolerated by quorum aggregation; seeing this error usually means you are inspecting a per-validator failure or too many validators misbehave.

Related errors


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