FuelLabs/fuel-core · critical
The consensus at override height {override_height} is not Po
Error message
The consensus at override height {override_height} is not PoA. What it means
On startup, make_database_compatible_with_config verifies blocks at PoAV2 override heights against the new consensus signing keys, rolling back if they mismatch. This error fires when the sealed block header at an override height carries a consensus seal that is not Consensus::PoA at all, so it cannot be verified against the PoA config.
Source
Thrown at crates/fuel-core/src/service.rs:326
let block_header = on_chain_view
.get_sealed_block_header(override_height)?
.ok_or(not_found!("SealedBlockHeader"))?;
let header = block_header.entity;
let seal = block_header.consensus;
if let Consensus::PoA(poa_seal) = seal {
let block_valid = verify_consensus(
start_up_consensus_config,
&header,
&poa_seal,
);
if !block_valid {
found_override_height = Some(override_height);
}
} else {
return Err(anyhow::anyhow!(
"The consensus at override height {override_height} is not PoA."
));
};
}
}
}
if let Some(override_height) = found_override_height {
let rollback_height = override_height.pred().ok_or(anyhow::anyhow!(
"The override height is zero. \
The override height should be greater than zero."
))?;
tracing::warn!(
"The consensus at override height {override_height} \
does not match with the database. \
Rollbacking the database to the height {rollback_height}"
);
combined_database.rollback_to(rollback_height, shutdown_listener)?;View on GitHub (pinned to b9d4d170da)
Solutions
- Start with a fresh database or a snapshot whose blocks are PoA-sealed and match the current consensus config
- Move the override heights so they only cover heights at/after blocks sealed under PoA with the new keys
- Verify you are running the same network/chain config that produced the database
Example fix
# before
# consensus.poa.signing_keys.overrides = { 1000 = "new_key" }
# DB contains a PoW-sealed block at height 1000
# after: wipe the mismatched DB or use a matching snapshot
rm -rf ~/.fuel/db
# or set overrides only at heights sealed with PoA:
# [consensus.poa.signing_keys.overrides]
# 5000 = "new_key" Defensive patterns
Strategy: validation
Validate before calling
// Rust operator: before starting with overrides, confirm the DB block at each override height is PoA-sealed
for &h in poa.get_all_overrides().keys() {
let sealed = on_chain_view.get_sealed_block_header(h)?.ok_or(not_found!("SealedBlockHeader"))?;
ensure!(matches!(sealed.consensus, Consensus::PoA(_)), "non-PoA block at {h}");
} Try / catch
match start_node().await { Err(e) if e.to_string().contains("is not PoA") => { /* wipe/resnapshot the DB to match the consensus config, or move override heights past non-PoA blocks */ } r => r } Prevention
- Never reuse a database across chains or consensus-type changes; resnapshot instead
- Set PoAV2 signing-key overrides only at heights at/after PoA-sealed blocks
- Record the chain config hash with each DB snapshot and diff before startup
When it happens
Trigger: Starting a node configured with PoAV2 signing-key overrides against a database whose block at that height was sealed with a different consensus variant (e.g. a PoW-sealed block from an old network, or data imported from another chain/config).
Common situations: Reusing a chain DB after switching consensus types or networks; override heights pointing at pre-migration blocks; snapshot/DB copied from a chain with different consensus; stale DB after a consensus-parameter/key rotation.
Related errors
- The override height is zero. The override height should be g
- The state of the service is not started: {state:?}
- The genesis block height is not found in the database during
- Block production timed out
- Manual block production is not allowed with trigger `Open`
AI-assisted analysis of FuelLabs/fuel-core@b9d4d170da (2026-08-16).
Data as JSON: /api/errors/d4856f91861be863.
Report an issue: GitHub.