diem/diem · error

We must not accept genesis from others

Error message

We must not accept genesis from others

What it means

Block::verify_well_formed() performs state-independent sanity checks and first ensures the block is not a genesis block (via is_genesis_block()). Genesis must come from local configuration, not from peers, so a genesis check here fails with 'We must not accept genesis from others'.

Source

Thrown at consensus/consensus-types/src/block.rs:240

    pub fn validate_signature(&self, validator: &ValidatorVerifier) -> anyhow::Result<()> {
        match self.block_data.block_type() {
            BlockType::Genesis => bail!("We should not accept genesis from others"),
            BlockType::NilBlock => self.quorum_cert().verify(validator),
            BlockType::Proposal { author, .. } => {
                let signature = self
                    .signature
                    .as_ref()
                    .ok_or_else(|| format_err!("Missing signature in Proposal"))?;
                validator.verify(*author, &self.block_data, signature)?;
                self.quorum_cert().verify(validator)
            }
        }
    }

    /// Makes sure that the proposal makes sense, independently of the current state.
    /// If this is the genesis block, we skip these checks.
    pub fn verify_well_formed(&self) -> anyhow::Result<()> {
        ensure!(
            !self.is_genesis_block(),
            "We must not accept genesis from others"
        );
        let parent = self.quorum_cert().certified_block();
        ensure!(
            parent.round() < self.round(),
            "Block must have a greater round than parent's block"
        );
        ensure!(
            parent.epoch() == self.epoch(),
            "block's parent should be in the same epoch"
        );
        if parent.has_reconfiguration() {
            ensure!(
                self.payload().map_or(true, |p| p.is_empty()),
                "Reconfiguration suffix should not carry payload"
            );
        }

View on GitHub (pinned to fc4714a8ea)

Solutions

  1. Filter out genesis blocks before calling verify_well_formed; initialize from the local genesis/waypoint instead.
  2. Reject the offending message and penalize/disconnect the peer sending genesis.
  3. Fix sync logic to source the parent chain head from local storage rather than network payloads.
  4. Ensure tests construct fresh proposal blocks rather than reusing genesis.

Example fix

// before
block.verify_well_formed()?;
// after
ensure!(!block.is_genesis_block(), "genesis must come from local config");
block.verify_well_formed()?;
Defensive patterns

Strategy: validation

Validate before calling

if block.is_genesis_block() {
    return Err(anyhow::anyhow!("genesis must be loaded locally, not from peers"));
}
block.verify_well_formed()?;

Type guard

fn is_network_block(block: &Block) -> bool {
    !block.is_genesis_block()
}

Try / catch

match block.verify_well_formed() {
    Ok(()) => { /* continue processing */ }
    Err(e) if e.to_string().contains("genesis") => {
        drop_peer(peer_id);
        metrics.genesis_offenses.inc();
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling block.verify_well_formed() when is_genesis_block() is true — the QC/block being checked wraps the genesis block received or constructed as an incoming proposal.

Common situations: A peer proposes/syncs genesis, test harness reusing the genesis block as a proposal, initial sync pulling a block that should be loaded from the local genesis file.

Related errors


AI-assisted analysis of diem/diem@fc4714a8ea (2026-09-04). Data as JSON: /api/errors/f431f0b8a7ef08f1. Report an issue: GitHub.