{"record":{"id":"51913bceea01c35a","repo":"nautechsystems/nautilus_trader","slug":"finalized-header-base-fee-is-invalid","errorCode":null,"errorMessage":"Finalized header base fee is invalid","messagePattern":"Finalized header base fee is invalid","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/cache/database.rs","lineNumber":3749,"sourceCode":"        let (number, hash, parent_hash, timestamp, base_fee, digest) = row;\n        anyhow::ensure!(\n            digest == manifest_digest,\n            \"Finalized header manifest identity changed\"\n        );\n        Ok(Some(ExecutionVerificationPosition {\n            next_canonical_nonce: u64::try_from(nonce).context(\"Canonical nonce is negative\")?,\n            revision: u64::try_from(revision).context(\"Canonical nonce revision is negative\")?,\n            finalized_tip: ExecutionVerifiedHeader {\n                number: u64::try_from(number).context(\"Finalized header number is negative\")?,\n                hash,\n                parent_hash,\n                timestamp: u64::try_from(timestamp)\n                    .context(\"Finalized header timestamp is negative\")?,\n                base_fee_per_gas: base_fee\n                    .map(|value| {\n                        value\n                            .parse::<u128>()\n                            .map_err(|_| anyhow::anyhow!(\"Finalized header base fee is invalid\"))\n                    })\n                    .transpose()?,\n            },\n        }))\n    }\n\n    pub(crate) async fn load_execution_verified_header(\n        &self,\n        chain_id: u32,\n        wallet_address: &str,\n        number: u64,\n        manifest_digest: &str,\n    ) -> anyhow::Result<Option<ExecutionVerifiedHeader>> {\n        let chain_id =\n            i32::try_from(chain_id).context(\"Verification chain ID exceeds PostgreSQL INTEGER\")?;\n        let number =\n            i64::try_from(number).context(\"Finalized header number exceeds PostgreSQL BIGINT\")?;\n        let row = sqlx::query_as::<_, (String, String, i64, Option<String>, String)>(","sourceCodeStart":3731,"sourceCodeEnd":3767,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/cache/database.rs#L3731-L3767","documentation":"Raised in database.rs:3749 when the nullable base_fee_per_gas TEXT column of a verified finalized header row cannot be parsed as a u128. The library stores numeric header fields as text and validates on read; a value that is not a valid unsigned integer means the persisted header data is corrupt or was written by a foreign writer.","triggerScenarios":"Loading the finalized tip in load_execution_verification_position when base_fee_per_gas is non-null but fails \"...\".parse::<u128>() (empty string, negative number, decimal, non-numeric text, or a value above u128 range).","commonSituations":"Manual row edits or data imports that wrote malformed base-fee strings; a bug in an older writer version encoding the fee differently; corrupted rows after a partial restore/migration.","solutions":["Inspect the offending row: SELECT number, base_fee_per_gas FROM execution_verified_finalized_header WHERE base_fee_per_gas IS NOT NULL AND base_fee_per_gas !~ '^[0-9]+$';","Re-record the header via verification bootstrap/re-ingestion from the chain so the base fee is stored as a canonical decimal string.","Restore the affected rows from a known-good backup if corruption is widespread.","Do not patch the string by hand; use the writer path so formatting stays consistent."],"exampleFix":"-- before: malformed value\nUPDATE ... base_fee_per_gas = '12.5 gwei'  -- breaks u128 parse\n\n-- after: canonical integer string in wei\n-- base_fee_per_gas = '12500000000'","handlingStrategy":"validation","validationCode":"let bad: Vec<(i64, Option<String>)> = sqlx::query_as(\n    \"SELECT number, base_fee_per_gas FROM execution_verified_finalized_header \\\n     WHERE chain_id = $1 AND base_fee_per_gas IS NOT NULL \\\n       AND base_fee_per_gas !~ '^[0-9]+$'\",\n).bind(chain_id).fetch_all(&pool).await?;\nassert!(bad.is_empty(), \"malformed base fee rows: {bad:?}\");","typeGuard":null,"tryCatchPattern":"match load_verified_header(...).await {\n    Err(e) if e.to_string().contains(\"Finalized header base fee is invalid\") => {\n        // flag row corrupt; re-ingest the header from the chain\n    },\n    other => other?,\n}","preventionTips":["Only write header rows through the library's writer path","Validate base-fee strings with a regex before bulk imports","Include base-fee format checks in database integrity tests"],"tags":["database","parsing","data-corruption","u128"],"backgroundTag":"invalid-argument-format","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"}