Skip to content
You are reading Hyperledger Besu development version documentation and some displayed features may not be available in the stable release. You can switch to stable version using the version box at screen bottom.
Last update: September 7, 2021

IBFT 2.0

Besu implements the IBFT 2.0 Proof-of-Authority (PoA) consensus protocol. Private networks can use IBFT 2.0.


Configure your network to ensure you never lose ⅓ or more of your validators. If more than ⅓ of validators stop participating, new blocks are no longer created, and the network stalls. It may take significant time to recover once nodes are restarted.

In IBFT 2.0 networks, approved accounts, known as validators, validate transactions and blocks. Validators take turns to create the next block. Before inserting the block onto the chain, a super-majority (greater than 66%) of validators must first sign the block.


You can use a plugin to securely store a validator’s key using the --security-module option.

Existing validators propose and vote to add or remove validators. Adding or removing a validator requires a majority vote (greater than 50%) of validators.

Minimum number of validators

IBFT 2.0 requires four validators to be Byzantine fault tolerant. Byzantine fault tolerance is the ability for a blockchain network to function correctly and reach consensus despite nodes failing or propagating incorrect information to peers.

Genesis file

To use IBFT 2.0, Besu requires an IBFT 2.0 genesis file. The genesis file defines properties specific to IBFT 2.0.

Example IBFT 2.0 genesis file

    "config": {
      "chainId": 1981,
      "muirglacierblock": 0,
      "ibft2": {
        "blockperiodseconds": 2,
        "epochlength": 30000,
        "requesttimeoutseconds": 4,
        "blockreward": "5000000000000000",
        "miningbeneficiary": "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73"
    "nonce": "0x0",
    "timestamp": "0x58ee40ba",
    "extraData": "0xf83ea00000000000000000000000000000000000000000000000000000000000000000d594c2ab482b506de561668e07f04547232a72897daf808400000000c0",
    "gasLimit": "0x1fffffffffffff",
    "difficulty": "0x1",
    "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
    "alloc": {}

The properties specific to IBFT 2.0 are:

  • blockperiodseconds - The minimum block time, in seconds.
  • epochlength - The number of blocks after which to reset all votes.
  • requesttimeoutseconds - The timeout for each consensus round before a round change, in seconds.
  • blockreward - Optional reward amount in Wei to reward the beneficiary. Defaults to zero (0). Can be specified as a hexadecimal (with 0x prefix) or decimal string value. If set, then all nodes on the network must use the identical value.
  • miningbeneficiary - Optional beneficiary of the blockreward. Defaults to the validator that proposes the block. If set, then all nodes on the network must use the same beneficiary.
  • extraData - RLP([32 bytes Vanity, List<Validators>, No Vote, Round=Int(0), 0 Seals]).


The blockperiodseconds, blockreward, and miningbeneficiary properties cannot be updated once your network is started.

We do not recommend changing epochlength in a running network. Changing the epochlength after genesis can result in illegal blocks.

The properties with specific values in the IBFT 2.0 genesis files are:

  • nonce - 0x0
  • difficulty - 0x1
  • mixHash - 0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365 for Istanbul block identification.

To start a node on an IBFT 2.0 private network, use the --genesis-file option to specify the custom genesis file.

Extra data

The extraData property is RLP encoded. RLP encoding is a space efficient object serialization scheme used in Ethereum. To generate the extraData RLP string for inclusion in the genesis file, use the rlp encode Besu subcommand.


besu rlp encode --from=toEncode.json

Where the toEncode.json file contains a list of the initial validators, in ascending order. To write the validator address and copy it to the toEncode.json file, use the public-key export-address Besu subcommand. For example:

One initial validator in toEncode.json file


Copy the RLP encoded data to the extraData property in the genesis file.

Block time

When the protocol receives a new chain head, the block time (blockperiodseconds) and round timeout (requesttimeoutseconds) timers start. When blockperiodseconds expires, the protocol proposes a new block.

If requesttimeoutseconds expires before adding the proposed block, a round change occurs, with the block time and timeout timers reset. The timeout period for the new round is two times requesttimeoutseconds. The timeout period continues to double each time a round fails to add a block.

Usually, the protocol adds the proposed block before reaching requesttimeoutseconds. A new round then starts, resetting the block time and round timeout timers. When blockperiodseconds expires, the protocol proposes the next new block.


If more than ⅓ of validators stop participating, new blocks can no longer be created and requesttimeoutseconds doubles with each round change. The quickest method to resume block production is to restart all validators, which resets requesttimeoutseconds to its genesis value.

Once blockperiodseconds is over, the time from proposing a block to adding the block is small (usually around one second) even in networks with geographically dispersed validators.


An internal network run by ConsenSys had four geographically dispersed validators in Sweden, Sydney, and two in North Virginia. With a blockperiodseconds of 5 and a requesttimeoutseconds of 10, the testnet consistently created blocks with a five second block time.

Tuning block timeout

To tune the block timeout for your network deployment:

  1. Set blockperiodseconds to your desired block time and requesttimeoutseconds to two times blockperiodseconds.
  2. Reduce requesttimeoutseconds until you start to see round changes occurring.
  3. Increase requesttimeoutseconds to the value where round changes are no longer occurring.


View TRACE logs to see round change log messages.

Optional configuration options

Optional configuration options in the genesis file are:

  • messageQueueLimit - In large networks with limited resources, increasing the message queue limit might help with message activity surges. The default is 1000.
  • duplicateMesageLimit - If the same node is retransmitting messages, increasing the duplicate message limit might reduce the number of retransmissions. A value of two to three times the number of validators is usually enough. The default is 100.
  • futureMessagesLimit - The future messages buffer holds messages for a future chain height. For large networks, increasing the future messages limit might be useful. The default is 1000.
  • futureMessagesMaxDistance - The maximum height from the current chain height for buffering messages in the future messages buffer. The default is 10.
Questions or feedback? You can discuss issues and obtain free support on Hyperledger Besu chat channel.
For Hyperledger Besu community support, contact the mailing list