nautechsystems/nautilus_trader · error · anyhow::Error

Profiler receipt contains {} logs at global index {}; expect

Error message

Profiler receipt contains {} logs at global index {}; expected exactly one

What it means

During profiler watermark verification, the library filters the transaction receipt's logs for one whose global log index matches the ingestion watermark's log_index, and requires exactly one match. If zero or multiple logs carry that index, the watermark cannot be unambiguously resolved, so the library throws rather than guessing.

Source

Thrown at crates/adapters/blockchain/src/execution/client.rs:4213

        receipt.status,
        "Profiler transaction did not execute successfully"
    );
    anyhow::ensure!(
        receipt.transaction_hash == transaction_hash,
        "Profiler receipt transaction hash does not match its ingestion watermark"
    );
    anyhow::ensure!(
        receipt.block_number == position.number
            && receipt.block_hash == expected_block_hash
            && receipt.transaction_index == u64::from(position.transaction_index),
        "Profiler receipt position does not match its ingestion watermark"
    );
    let matching_logs = receipt
        .logs
        .iter()
        .filter(|log| rpc_log::extract_log_index(log).ok() == Some(position.log_index))
        .collect::<Vec<_>>();
    anyhow::ensure!(
        matching_logs.len() == 1,
        "Profiler receipt contains {} logs at global index {}; expected exactly one",
        matching_logs.len(),
        position.log_index
    );
    let log = matching_logs[0];
    let log_transaction_hash = B256::from_str(&rpc_log::extract_transaction_hash(log)?)
        .with_context(|| "Invalid profiler log transaction hash")?;
    let log_block_hash = log
        .block_hash
        .as_deref()
        .ok_or_else(|| anyhow::anyhow!("Profiler log has no block hash"))?;
    anyhow::ensure!(
        !log.removed
            && log_transaction_hash == transaction_hash
            && rpc_log::extract_block_number(log)? == position.number
            && rpc_log::extract_transaction_index(log)? == position.transaction_index
            && B256::from_str(log_block_hash)? == expected_block_hash,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Log the receipt's full log list with extracted indices and compare against position.log_index to see whether it is 0 or >1 matches.
  2. Re-fetch the receipt from a different/fuller RPC provider if logs appear truncated.
  3. Verify the watermark position was produced by the same node/provider that serves the receipt.
  4. Upgrade or fix the node indexing if duplicate log indices are returned.
Defensive patterns

Strategy: validation

Validate before calling

let matches: Vec<_> = receipt.logs.iter()
    .filter(|l| extract_log_index(l).ok() == Some(position.log_index))
    .collect();
if matches.len() != 1 { /* re-fetch receipt from another provider */ }

Try / catch

match client.validate_watermark_log(&receipt, &position).await {
    Ok(log) => log,
    Err(e) if e.to_string().contains("expected exactly one") => fallback_provider_fetch(e),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling the profiler validation with a receipt whose logs either do not contain the log at position.log_index (0 matches, e.g. logs truncated by the RPC provider) or where extract_log_index returns the same index for multiple logs (duplicate indexing by a broken RPC).

Common situations: RPC providers that omit or truncate receipt logs; misconfigured tracing/indexing nodes; a data-feed watermark advanced past what the execution node has; provider bugs returning duplicated log entries.

Related errors


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