{"record":{"id":"aa4d76f258dd6878","repo":"nautechsystems/nautilus_trader","slug":"failed-to-validate-finalized-checkpoint-ledger-e","errorCode":null,"errorMessage":"Failed to validate finalized checkpoint ledger: {e}","messagePattern":"Failed to validate finalized checkpoint ledger: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/cache/database.rs","lineNumber":4403,"sourceCode":"        .bind(checkpoint_timestamp)\n        .bind(base_fee)\n        .bind(bootstrap.manifest_digest)\n        .execute(&mut *transaction)\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to initialize finalized header ledger: {e}\"))?;\n        let stored_checkpoint = sqlx::query_as::<_, (String, String, i64, Option<String>)>(\n            \"\n            SELECT hash, parent_hash, timestamp, base_fee_per_gas\n            FROM execution_verified_finalized_header\n            WHERE chain_id = $1 AND wallet_address = $2 AND number = $3\n            \",\n        )\n        .bind(chain_id)\n        .bind(bootstrap.wallet_address)\n        .bind(checkpoint_number)\n        .fetch_one(&mut *transaction)\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to validate finalized checkpoint ledger: {e}\"))?;\n        anyhow::ensure!(\n            stored_checkpoint\n                == (\n                    bootstrap.checkpoint_hash.to_string(),\n                    bootstrap.checkpoint_parent_hash.to_string(),\n                    checkpoint_timestamp,\n                    bootstrap\n                        .checkpoint_base_fee_per_gas\n                        .map(|value| value.to_string()),\n                ),\n            \"Finalized checkpoint ledger conflicts with the trusted chain anchor\"\n        );\n\n        if initialized {\n            let stored_tip =\n                sqlx::query_as::<_, (i64, String, String, i64, Option<String>, String)>(\n                    \"\n                SELECT number, hash, parent_hash, timestamp, base_fee_per_gas, manifest_digest","sourceCodeStart":4385,"sourceCodeEnd":4421,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/cache/database.rs#L4385-L4421","documentation":"This error wraps a sqlx failure on the SELECT that reads back the just-written checkpoint row from `execution_verified_finalized_header`. After inserting the checkpoint, the code fetches it (fetch_one) to verify what was durably stored; if the row cannot be fetched — table missing, connection failure, or the row genuinely absent — the error surfaces with this message.","triggerScenarios":"fetch_one returns zero rows (RowNotFound) because the preceding ON CONFLICT DO NOTHING insert was skipped while the row was later deleted, or because a trigger/cleanup removed it; schema drift on the table; connection drop mid-transaction.","commonSituations":"External cleanup jobs pruning rows between the INSERT and SELECT (same transaction, so usually a connection issue); running against a database where another process manages the table; Postgres failover breaking the transaction; stale schema missing columns hash/parent_hash/timestamp/base_fee_per_gas.","solutions":["Read the wrapped sqlx error: 'no rows returned' (RowNotFound) means the checkpoint row vanished — check for external jobs modifying `execution_verified_finalized_header`; 'relation does not exist' means run schema migrations.","Verify nothing outside this transaction deletes or modifies rows at the checkpoint (chain_id, wallet_address, number).","Confirm the preceding checkpoint INSERT succeeded and committed in the same transaction (no partial commits).","Check connection health/pool settings; re-run bootstrap after transient DB issues — it is idempotent."],"exampleFix":"// before\n.fetch_one(&mut *transaction)\n.await\n.map_err(|e| anyhow::anyhow!(\"Failed to validate finalized checkpoint ledger: {e}\"))?;\n\n// after\n.fetch_one(&mut *transaction)\n.await\n.map_err(|e| {\n    anyhow::anyhow!(\n        \"Failed to validate finalized checkpoint ledger at number {checkpoint_number}: {e:#}\"\n    )\n})?;","handlingStrategy":"validation","validationCode":"// After inserting the checkpoint, use fetch_optional and distinguish 'missing' from 'error'\nlet stored: Option<(String, String, i64, Option<String>)> = sqlx::query_as(\n    \"SELECT hash, parent_hash, timestamp, base_fee_per_gas FROM execution_verified_finalized_header WHERE chain_id=$1 AND wallet_address=$2 AND number=$3\",\n).bind(chain_id).bind(wallet).bind(number).fetch_optional(&mut *tx).await?;\nanyhow::ensure!(stored.is_some(), \"checkpoint row missing after insert — external deletion detected\");","typeGuard":null,"tryCatchPattern":"match result {\n    Err(sqlx::Error::RowNotFound) => return Err(anyhow!(\"checkpoint row vanished between insert and read — check for external table mutations\")),\n    Err(e) => return Err(anyhow!(\"checkpoint validation failed: {e:#}\")),\n    Ok(row) => verify(row),\n}","preventionTips":["Never run external cleanup/pruning jobs against execution_verified_finalized_header while the adapter runs","Keep the insert and read-back in the same transaction (already the case) so visibility is consistent","Alert on RowNotFound for rows the adapter itself just wrote","Restore databases from matching-version snapshots only"],"tags":["database","sqlx","postgres","read-back"],"backgroundTag":"database-query-failed","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"}