linera-io/linera-protocol · critical · ExecutionError

OracleResponseMismatch

OracleResponseMismatch

Error message

ExecutionError::OracleResponseMismatch

What it means

Linera records every oracle response (cross-chain balance reads, blob reads, etc.) when a block is first executed, and replays them when the block is re-executed by validators or workers. TransactionTracker::replay_oracle_response compares each freshly produced response against the next recorded one; OracleResponseMismatch means the same transaction produced a different oracle answer than the one recorded in the proposal or certificate.

Source

Thrown at linera-execution/src/transaction_tracker.rs:339

                                first_index,
                                next_index,
                            }
                        },
                    )
                    .collect();
                (app_id, updates)
            })
            .collect()
    }

    /// Adds the oracle response to the record.
    /// If replaying, it also checks that it matches the next replayed one and returns `true`.
    pub fn replay_oracle_response(
        &mut self,
        oracle_response: OracleResponse,
    ) -> Result<bool, ExecutionError> {
        let replaying = if let Some(recorded_response) = self.next_replayed_oracle_response()? {
            ensure!(
                recorded_response == oracle_response,
                ExecutionError::OracleResponseMismatch
            );
            true
        } else {
            false
        };
        self.oracle_responses.push(oracle_response);
        Ok(replaying)
    }

    /// If in replay mode, returns the next oracle response, or an error if it is missing.
    ///
    /// If not in replay mode, `None` is returned, and the caller must execute the actual oracle
    /// to obtain the value.
    ///
    /// In both cases, the value (returned or obtained from the oracle) must be recorded using
    /// `add_oracle_response`.

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Make application oracle reads deterministic: never branch on wall-clock time, randomness, or remote-chain state read outside the recorded oracle
  2. Verify that all executing nodes hold the same view of the referenced chain/blob (sync storage, check pruning policy)
  3. If you maintain a worker or custom client, treat this error as a reason to reject the block or certificate, not retry it, then re-download state from a committee validator
  4. Check for version skew between proposer and validator: the oracle response encoding has changed across Linera versions

Example fix

// before
let matched = tracker.replay_oracle_response(response)?; // mismatch aborts with no context

// after
match tracker.replay_oracle_response(response) {
    Ok(replaying) => { /* continue */ }
    Err(ExecutionError::OracleResponseMismatch) => {
        // deterministic divergence: reject the block, do not retry
        return Err(anyhow::anyhow!("oracle divergence on block replay"));
    }
    Err(e) => return Err(e.into()),
}
Defensive patterns

Strategy: try-catch

Try / catch

Match ExecutionError::OracleResponseMismatch explicitly around replay_oracle_response / execute_transaction calls. It is a deterministic divergence, not a transient fault: reject or quarantine the block, resynchronize state from a committee validator, and never retry the same replay against the same data.

Prevention

When it happens

Trigger: Re-executing a block via handle_request, apply_checkpoint, or blob_used where an oracle query (e.g. the balance of another chain, a blob's content) now returns a value different from the one recorded when the block was proposed and signed.

Common situations: Non-deterministic application logic that reads remote state which changed between proposal and validation; two executing nodes holding different views of the same cross-chain state; pruned or rewritten blobs; a malicious proposer fabricating oracle responses.

Related errors


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