x/staking and enterprise/poa modules, and realizes a design first proposed in 2019 as ADR-016.
Which keys rotate
A validator runs on three keys, each with a different owner and job:- Operator key: an ordinary account key that the operator generates and custodies, often on a hardware wallet or behind a multisig. It owns the validator: it stakes, sets commission, edits the validator’s description, withdraws rewards, votes, and signs the rotation message itself. Like any account key, it has no in-place replacement; retiring one means creating a new account and moving funds.
- Consensus key: generated by the stack when a node initializes, stored in
priv_validator_key.jsonor held by a remote signer. It is a raw keypair with no mnemonic behind it; the operator custodies the file, not a seed phrase. It signs the validator’s vote on every block, and a block proposal whenever the validator’s turn comes to propose. Evidence of misbehavior identifies the validator through this key’s consensus address. This is the only key a rotation touches. - Node key: the node’s peer-to-peer identity. It exists so peers can address and authenticate each other: its public key hashes to the node ID used in peer addresses, and it secures the connection handshake between nodes. It carries no on-chain state and regenerates freely.
How a rotation works
The operator submitsMsgRotateConsPubKey, carrying the new consensus public key. Everything that defines the validator stays put: the operator address, voting power, delegations, and commission. Only the consensus key and its index change.
The new key does not take effect immediately. The chain emits the power hand-off to CometBFT right away, setting the old key to zero and giving the new key the validator’s full power, and CometBFT’s validator update rule makes it effective two heights later, at the same height the chain swaps its stored key. Zero downtime rides on this: the operator runs a second node with the new key alongside the old one. Until the rotation takes effect, the second node follows the chain as a non-signing full node, because a CometBFT node whose key is outside the validator set produces no votes. The moment the new key enters the set, the second node starts signing, the old key holds no power, and the operator retires the old node. The step-by-step procedure is in Rotate a consensus key, Staking.
Safety rails
Three rules bound what a rotation can do:- A rotation burns a flat fee, set by the
key_rotation_feestaking param, to make rotation spam expensive. - A validator can rotate once per unbonding period. Until the unbonding period ends, the previous key remains accountable, so the chain rejects a second rotation inside the window.
- A rotation cannot be undone. No cancel message exists, and the once-per-unbonding-period limit blocks an immediate rotation back, so an applied rotation stands until the window expires.
Security implications
Read this section carefully. Key rotation introduces security and performance tradeoffs that chains must be aware of before rotating keys.
Slashing window length
Slashing follows a validator’s history, not the key. Evidence of a double sign under the old key still slashes the validator after rotation. When a rotation lands, the chain records the old consensus address. It keeps that address tied to the validator. It tracks the address for as long as evidence against it can still be admitted. It computes this window at rotation time from the evidence paramsMaxAgeNumBlocks and MaxAgeDuration. Once both elapse, the chain stops tracking the address. The window can be months, depending on the chain’s evidence settings. Rotating away from a key does not let a validator escape slashing within that window.
Downtime slashing carries over too. On a rotation, the validator’s missed-block record and jailed status move to the new consensus key. A rotation does not reset them.
The chain computes a rotation tracking window once at the time of rotation. It never updates this window. If governance extends MaxAgeNumBlocks or MaxAgeDuration after a rotation, the original window for the rotation remains in effect. In this scenario, the old consensus address will stop being tracked before the current evidence window closes. During that gap, a double sign under the old key cannot be slashed. This is a risk that chains should be aware of. Do not extend the evidence params while rotations are in flight without accounting for it.
Increased IBC light client updates
Frequent rotations may raise the cost of keeping a light client current. Each rotation changes the validator set. Tendermint light clients advance using the overlap between successive validator sets. Heavy rotation churn shrinks that overlap. With less overlap, a relayer must submit more update-client messages to advance the client across the same span. The once-per-unbonding-period limit exists partly to bound this cost.Proposer priority reset
Rotation resets the validator’s proposer priority. CometBFT orders validators by a proposer priority value. That value decides when a validator’s turn to propose comes up. A rotation sends the validator to the back of that order. This holds even if the validator was next in line to propose.Slower signature verification
A validator set with mixed consensus key types verifies signatures more slowly. CometBFT batch-verifies signatures when every validator uses the same key type. Batch verification is faster than checking each signature on its own. One validator on a different key type breaks batching. Verification then falls back to one signature at a time, which can slow block times. This applies whenever the set holds more than one key type, not only during a rotation.Exports and restarts
In-progress rotations survive a genesis export. A chain exported mid-rotation carries the pending rotation and its remaining history window into the new genesis, so restarting a chain does not lose slashing accountability or drop a queued key change.Staking and PoA chains
Rotation ships in both validator models. On staked chains, it is thex/staking implementation described above; for the procedure, see Rotate a consensus key, Staking. Chains running enterprise/poa get the same rotation with two differences. The admin can rotate any validator’s key, not only the operator. And because PoA has no slashing or evidence handling, the safety rails above do not apply: no fee, no rate limit, no rotation history, and the state swap happens in the block the transaction lands. For the procedure, see Rotate a consensus key, PoA.
The PoS and PoA models differ in how they handle CometBFT’s two-height delay. After a key rotation, CometBFT keeps signing LastCommit with the old consensus address for two heights. Staking waits out those heights before swapping its own state and keeps a historical address mapping, so the old address still resolves to its validator. PoA swaps immediately and keeps no mapping, so during those two heights it cannot resolve the old address that LastCommit still carries. A stock PoA chain never notices, because it runs neither x/distribution nor x/slashing (the modules that generally read those addresses). However, custom logic that resolves a validator from a LastCommit address on a PoA chain will not find a rotating validator for those two heights, which can lead to unexpected behavior.
For this reason, vote extensions are not supported on PoA chains. The chain verifies a vote-extension signature by the LastCommit address. If a validator rotates its key during the two-height delay, the chain will reject the vote extension because the LastCommit address will not resolve to the validator. The standard ValidateVoteExtensions helper returns an error on the first commit vote whose LastCommit address it cannot resolve, before it tallies any voting power. One rotating validator that signed the previous block is therefore enough to have the whole extended commit rejected, whatever its share of voting power.
Next steps
- Perform a rotation on a staked chain. See Rotate a consensus key, Staking.
- Perform a rotation on a PoA chain. See Rotate a consensus key, PoA.
- Understand the key types. See Post-quantum keys.
- Look up the message, parameters, and state layout. See the x/staking module reference.