{"record":{"id":"c739b7f4b4bc84b0","repo":"nautechsystems/nautilus_trader","slug":"profiler-receipt-position-does-not-match-its-inges","errorCode":null,"errorMessage":"Profiler receipt position does not match its ingestion watermark","messagePattern":"Profiler receipt position does not match its ingestion watermark","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":4202,"sourceCode":"    let transaction_hash = B256::from_str(&position.transaction_hash).with_context(|| {\n        format!(\n            \"Invalid profiler transaction hash {}\",\n            position.transaction_hash\n        )\n    })?;\n    let receipt = verified_value(\n        verification.verify_receipt(&transaction_hash).await,\n        \"profiler watermark receipt\",\n    )?;\n    anyhow::ensure!(\n        receipt.status,\n        \"Profiler transaction did not execute successfully\"\n    );\n    anyhow::ensure!(\n        receipt.transaction_hash == transaction_hash,\n        \"Profiler receipt transaction hash does not match its ingestion watermark\"\n    );\n    anyhow::ensure!(\n        receipt.block_number == position.number\n            && receipt.block_hash == expected_block_hash\n            && receipt.transaction_index == u64::from(position.transaction_index),\n        \"Profiler receipt position does not match its ingestion watermark\"\n    );\n    let matching_logs = receipt\n        .logs\n        .iter()\n        .filter(|log| rpc_log::extract_log_index(log).ok() == Some(position.log_index))\n        .collect::<Vec<_>>();\n    anyhow::ensure!(\n        matching_logs.len() == 1,\n        \"Profiler receipt contains {} logs at global index {}; expected exactly one\",\n        matching_logs.len(),\n        position.log_index\n    );\n    let log = matching_logs[0];\n    let log_transaction_hash = B256::from_str(&rpc_log::extract_transaction_hash(log)?)","sourceCodeStart":4184,"sourceCodeEnd":4220,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L4184-L4220","documentation":"This is a consistency check in the execution client's profiler watermark verification. After fetching a transaction receipt, the library verifies that the receipt's block number, block hash, and transaction index exactly match the ingestion watermark position used to locate it. If the receipt was mined/reorged into a different position than expected, this error is thrown to prevent building the profiler watermark on stale or inconsistent data.","triggerScenarios":"Calling the profiler watermark validation path (validate receipt against position) when the receipt's block_number != position.number, receipt.block_hash != expected_block_hash, or receipt.transaction_index != position.transaction_index. Typically triggered by a chain reorg between watermark ingestion and receipt fetch, or querying a different/inconsistent RPC endpoint.","commonSituations":"Reorged blocks on a testnet/local fork; load-balanced RPC endpoints backed by out-of-sync nodes; an execution RPC endpoint lagging behind the data feed; running the profiler against a snapshot that has since been reorganized.","solutions":["Re-run the profiler watermark validation after the reorg settles; confirm the block is stable (wait confirmations).","Point the execution RPC endpoint to a node consistent with the data feed (same provider/region, no mixed fallback nodes).","Verify expected_block_hash and position come from the same latest-block query, not cached/stale state.","Pin a single RPC endpoint instead of a round-robin load balancer to avoid cross-node inconsistency."],"exampleFix":"// before: single-shot fetch, no reorg tolerance\nlet receipt = rpc.get_transaction_receipt(tx_hash).await?;\nvalidate_receipt_position(&receipt, &position, expected_block_hash)?;\n\n// after: retry on reorg with fresh position\nfor _ in 0..3 {\n    let (position, expected_block_hash) = fetch_latest_position(&rpc).await?;\n    let receipt = rpc.get_transaction_receipt(tx_hash).await?;\n    match validate_receipt_position(&receipt, &position, expected_block_hash) {\n        Ok(()) => break,\n        Err(_) => tokio::time::sleep(Duration::from_secs(2)).await,\n    }\n}","handlingStrategy":"retry","validationCode":"let latest = rpc.get_block_number().await?;\nassert!(position.number <= latest, \"watermark position ahead of chain\");\nassert_eq!(receipt.block_number, position.number);","typeGuard":"fn receipt_matches_position(receipt: &Receipt, position: &Position) -> bool {\n    receipt.block_number == position.number\n        && receipt.transaction_index as u64 == position.transaction_index\n}","tryCatchPattern":"match client.fetch_profiler_receipt(tx_hash).await {\n    Ok(r) => r,\n    Err(e) if e.to_string().contains(\"receipt position does not match\") => retry_after_confirmations(e),\n    Err(e) => return Err(e),\n}","preventionTips":["Pin a single RPC node for watermark ingestion and receipt fetch","Wait several confirmations before validating watermark positions","Monitor for reorgs and re-ingest from canonical blocks"],"tags":["blockchain","reorg","consistency","rpc"],"backgroundTag":"internal-invariant-violation","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}