hyperledger/fabric · error

The supplied bytes are not of genesis block. blockNum=%d, bl

Error message

The supplied bytes are not of genesis block. blockNum=%d, blockHash=%x

What it means

assertIsGenesisBlock verifies that bytes supplied to a rollback/restore path (via retrieveGenesisBlkOffsetAndMakeACopy) actually serialize to a block whose header number is 0 and whose data hash is non-nil. If not, it throws "The supplied bytes are not of genesis block. blockNum=%d, blockHash=%x" so the ledger file reset does not copy a wrong block as the genesis anchor.

Source

Thrown at common/ledger/blkstorage/reset.go:118

	if err := assertIsGenesisBlock(genesisBlockBytes); err != nil {
		return "", -1, err
	}
	// just for an extra safety make a backup of genesis block
	if err := os.WriteFile(path.Join(ledgerDir, "__backupGenesisBlockBytes"), genesisBlockBytes, 0o640); err != nil {
		return "", -1, err
	}
	logger.Infof("Genesis block backed up. Genesis block info file [%s], offset [%d]", blockfilePath, endOffsetGenesisBlock)
	return blockfilePath, endOffsetGenesisBlock, nil
}

func assertIsGenesisBlock(blockBytes []byte) error {
	block, err := deserializeBlock(blockBytes)
	if err != nil {
		return err
	}
	if block.Header.Number != 0 || block.Header.GetDataHash() == nil {
		return fmt.Errorf("The supplied bytes are not of genesis block. blockNum=%d, blockHash=%x", block.Header.Number, block.Header.GetDataHash())
	}
	return nil
}

func pathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if os.IsNotExist(err) {
		return false, nil
	}
	if err != nil {
		return false, err
	}
	return true, nil
}

const (
	fileNamePreRestHt = "__preResetHeight"
)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Confirm you are rolling back the correct ledger directory/channel and that the genesis block (block 0) file is present and intact.
  2. Restore the genesis block from a backup or snapshot before retrying the rollback/restore.
  3. If the ledger is unrecoverable, reset the ledger and re-join/re-sync the channel from peers.

Example fix

// before
peer node rollback --channelID mychannel --blockNumber 100 // ledger dir missing block 0 file
// after
restore the earliest blockfile containing the genesis block, then:
peer node rollback --channelID mychannel --blockNumber 100
Defensive patterns

Strategy: validation

Validate before calling

block, err := deserializeBlock(blockBytes)
if err != nil {
    return err
}
if block.Header.Number != 0 || block.Header.GetDataHash() == nil {
    return fmt.Errorf("refusing rollback: bytes are block %d, not genesis", block.Header.Number)
}

Try / catch

if err := assertIsGenesisBlock(blockBytes); err != nil {
    var numErr *fmt.NumError
    _ = numErr
    return fmt.Errorf("aborting rollback: %w", err)
}

Prevention

When it happens

Trigger: Calling the rollback/restore flow and providing a block file or byte range that is not the genesis block: offset points to block 1+, the ledger dir contains no genesis block, or the file was overwritten/truncated so deserialization yields a non-zero block number.

Common situations: Rollback (peer node rollback) run against a ledger whose first block file no longer holds block 0 (earlier truncation, cleanup of old files), pointing the tool at the wrong channel/ledger directory, or corrupted genesis record.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/98d981380b8e5469. Report an issue: GitHub.