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
- 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.
- Re-fetch the receipt from a different/fuller RPC provider if logs appear truncated.
- Verify the watermark position was produced by the same node/provider that serves the receipt.
- 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
- Use full-fidelity RPC providers that do not truncate receipt logs
- Cross-check log counts between data feed and execution node
- Alert when receipt.log_len differs from the feed's expectations
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
- RPC tick {tick_value} does not match positions: derived gros
- Fetched block {} while requesting RPC snapshot block {}
- Profiler receipt position does not match its ingestion water
- Profiler log has no block hash
- Profiler log position does not match its ingestion watermark
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/88645a378a560dd3.
Report an issue: GitHub.