FuelLabs/fuel-core · error · anyhow::Error
contract tx_pointer cannot be greater than genesis block
Error message
contract tx_pointer cannot be greater than genesis block
What it means
Thrown by init_contract_latest_utxo during on-chain genesis import. Each ContractsLatestUtxo entry records the utxo that last created or updated a contract, and its tx_pointer must reference a block at or below the height of the genesis block being imported. When entry.value.tx_pointer().block_height() exceeds that height, the contract would point at a block that does not exist yet at genesis, so the import is rejected.
Source
Thrown at crates/fuel-core/src/service/genesis/importer/on_chain.rs:257
.storage::<Coins>()
.replace(&utxo_id, &compressed_coin)?
.is_some()
{
return Err(anyhow!("Coin should not exist"));
}
Ok(())
}
fn init_contract_latest_utxo(
transaction: &mut StorageTransaction<&mut GenesisDatabase>,
entry: &TableEntry<ContractsLatestUtxo>,
height: BlockHeight,
) -> anyhow::Result<()> {
let contract_id = entry.key;
if entry.value.tx_pointer().block_height() > height {
return Err(anyhow!(
"contract tx_pointer cannot be greater than genesis block"
));
}
if transaction
.storage::<ContractsLatestUtxo>()
.replace(&contract_id, &entry.value)?
.is_some()
{
return Err(anyhow!("Contract utxo should not exist"));
}
Ok(())
}
fn init_blob_payload(
transaction: &mut StorageTransaction<&mut GenesisDatabase>,
entry: &TableEntry<BlobData>,View on GitHub (pinned to b9d4d170da)
Solutions
- Raise the genesis block height in the chain config so it is greater than or equal to the maximum tx_pointer block height across all ContractsLatestUtxo entries.
- Or rewrite the offending entries' tx_pointer block heights to values at or below the genesis height (regenerating the snapshot is safer than hand edits).
- Re-export the snapshot at the exact height you declare as genesis so heights stay consistent.
Example fix
// before: chain config declares genesis height 42,
// but a contracts_latest_utxo entry has tx_pointer.block_height = 50
{ "tx_pointer": { "block_height": 50, "tx_index": 0 } }
// after: make the genesis height cover the pointer
// chain_config: "height": 50
// (or set the entry's tx_pointer.block_height to <= 42) Defensive patterns
Strategy: validation
Validate before calling
fn validate_contract_utxo_heights(
entries: &[TableEntry<ContractsLatestUtxo>],
genesis_height: u32,
) -> Result<(), String> {
for e in entries {
if e.value.tx_pointer().block_height().as_u32() > genesis_height {
return Err(format!(
"contract {} tx_pointer height {} above genesis height {}",
e.key,
e.value.tx_pointer().block_height(),
genesis_height
));
}
}
Ok(())
} Try / catch
match importer.run().await {
Err(e) if e.to_string().contains("tx_pointer cannot be greater than genesis") => {
// fix snapshot heights or raise genesis height; not retryable as-is
}
rest => rest,
} Prevention
- Always export snapshots at the exact height declared as genesis.
- Add a CI check comparing max tx_pointer height across state tables against the declared genesis height.
- Never hand-edit tx_pointer fields in snapshots.
When it happens
Trigger: A genesis or state snapshot whose contracts_latest_utxo entries carry tx_pointer block heights greater than the genesis block height set in the chain config — for example exporting state at height H but declaring a lower genesis height, or hand-editing tx_pointer fields.
Common situations: Building a test-network genesis from a snapshot taken at a higher height; shrinking the declared genesis height to compress the chain without rewriting snapshot pointers; snapshot tooling version changes that emit absolute instead of relative heights.
Related errors
- Coin should not exist
- Contract utxo should not exist
- Blob should not exist
- Contract code should not exist
- message da_height cannot be greater than genesis da block he
AI-assisted analysis of FuelLabs/fuel-core@b9d4d170da (2026-08-16).
Data as JSON: /api/errors/fdb1dfff268e25aa.
Report an issue: GitHub.