{"record":{"id":"29b004bb94dd11f4","repo":"nautechsystems/nautilus_trader","slug":"chain-checkpoint-hash-must-be-nonzero","errorCode":null,"errorMessage":"Chain checkpoint hash must be nonzero","messagePattern":"Chain checkpoint hash must be nonzero","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/rpc/verification.rs","lineNumber":1220,"sourceCode":"        }\n    }\n\n    let endpoints = [\n        normalize_endpoint(authoritative_url)?,\n        normalize_endpoint(config.verifiers[0].http_rpc_url.expose_secret())?,\n        normalize_endpoint(config.verifiers[1].http_rpc_url.expose_secret())?,\n    ];\n    ensure_distinct(endpoints.iter().map(String::as_str), \"provider endpoints\")?;\n\n    let anchor = &config.chain_anchor;\n    anyhow::ensure!(anchor.chain_id != 0, \"Chain anchor ID must be nonzero\");\n    anyhow::ensure!(\n        !anchor.chain_name.trim().is_empty(),\n        \"Chain anchor name is required\"\n    );\n    let checkpoint_hash = B256::from_str(&anchor.checkpoint_hash)\n        .map_err(|_| anyhow::anyhow!(\"Chain checkpoint hash must contain 32 hexadecimal bytes\"))?;\n    anyhow::ensure!(\n        checkpoint_hash != B256::ZERO,\n        \"Chain checkpoint hash must be nonzero\"\n    );\n    anyhow::ensure!(\n        anchor.max_head_skew_blocks != 0\n            && anchor.max_head_age_secs != 0\n            && anchor.max_future_drift_secs != 0,\n        \"Chain head skew, age, and future-drift limits must be nonzero\"\n    );\n    anyhow::ensure!(\n        !config.manifest_version.trim().is_empty(),\n        \"Deployment manifest version is required\"\n    );\n    let manifest_digest = B256::from_str(&config.manifest_digest).map_err(|_| {\n        anyhow::anyhow!(\"Deployment manifest digest must contain 32 hexadecimal bytes\")\n    })?;\n    anyhow::ensure!(\n        manifest_digest != B256::ZERO,","sourceCodeStart":1202,"sourceCodeEnd":1238,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/rpc/verification.rs#L1202-L1238","documentation":"During chain anchor validation in the RPC verification layer, the anchor's checkpoint_hash is parsed into a 32-byte B256 and rejected if it equals B256::ZERO. A zero hash is never a valid checkpoint root, so the library treats it as a placeholder or uninitialized value. This guard prevents anchoring chain verification to a meaningless digest.","triggerScenarios":"Calling the verification setup that validates a ChainAnchor whose `checkpoint_hash` field parses to valid hex but is exactly 32 zero bytes (0x0000...0000).","commonSituations":"A stub or template config where the hash was never filled in; an operator zeroing the field to 'disable' checkpoint checks; generated configs defaulting the hash to all zeros.","solutions":["Set `anchor.checkpoint_hash` to the real 32-byte keccak digest of the checkpoint block or state root.","Copy the checkpoint hash exactly as published by the chain operator (0x-prefixed 64 hex chars).","If the hash is unknown, fetch it from the deployment's canonical manifest or the chain's finalized checkpoint rather than guessing."],"exampleFix":"// before\nlet anchor = ChainAnchor { chain_name: \"base\".into(), checkpoint_hash: \"0x0000000000000000000000000000000000000000000000000000000000000000\".into(), ..Default::default() };\n// after\nlet anchor = ChainAnchor { chain_name: \"base\".into(), checkpoint_hash: \"0x9f2c...ab01\".into(), ..Default::default() }; // real 32-byte hash","handlingStrategy":"validation","validationCode":"fn checkpoint_hash_ok(anchor: &ChainAnchor) -> bool {\n    B256::from_str(&anchor.checkpoint_hash)\n        .map(|h| h != B256::ZERO)\n        .unwrap_or(false)\n}\nassert!(checkpoint_hash_ok(&anchor), \"checkpoint_hash must be a nonzero 32-byte hex value\");","typeGuard":"fn is_nonzero_b256(s: &str) -> Option<B256> {\n    B256::from_str(s).ok().filter(|h| *h != B256::ZERO)\n}","tryCatchPattern":null,"preventionTips":["Load checkpoint hashes from the chain operator's published deployment file, never hand-typed.","Add a unit test asserting every bundled anchor has a nonzero checkpoint hash.","Reject all-zero hex literals in config linting before deployment."],"tags":["validation","config","blockchain"],"backgroundTag":"invalid-config-value","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"}