enterprise/poa module. PoA rotation drops three of the staking rails: there is no fee, no rate limit, and no rotation history. PoA chains have no slashing or evidence handling to protect. The operator can rotate its own key, and the chain admin can rotate any validator’s key. For how rotation works in general, see Key rotation.
Commands use simd. Substitute your chain’s binary. Examples use ~/.node for the validator node’s home, ~/.poa-newkey for the scratch home holding the new key, and val for the operator key name.
Prerequisites
- The chain runs
enterprise/poav1.1 or later. - jq and curl. The commands extract the new public key with jq and watch the validator set with curl.
- A running PoA validator you operate, with the chain’s binary on your PATH and a secondary machine or scratch directory for the new key.
- The new key’s type is in the chain’s consensus params. See Enable ML-DSA keys.
- The signer is the validator’s operator, or the chain admin. Any other sender is rejected.
1. Generate a new consensus key
Create the new key on a secondary machine or offline. Do not touch the live node’spriv_validator_key.json yet:
To rotate to a post-quantum key, add
--consensus-key-algo ml_dsa_65 to the command above. See Migrate a validator to ML-DSA.~/.poa-newkey/config/priv_validator_key.json, which is the new consensus key. Confirm it and read its public key:
2. Submit the rotation
The command takes the new public key as base64 plus its type, and identifies the validator by operator address. Both derive from earlier steps:To rotate to a post-quantum key, pass
ml_dsa_65 instead of ed25519 in the command above. See Migrate a validator to ML-DSA.cosmos1...), not a cosmosvaloper1... address, so read it with simd keys show val -a.
Add standard transaction flags as your setup requires: --chain-id and --keyring-backend if your client config does not supply them, and --fees (or --gas-prices) to meet the chain’s minimum gas price.
The transaction re-keys the validator’s state and migrates its accrued fees in the same block. Power, metadata, and the operator address are unchanged.
To rotate as the admin instead, keep the command identical and sign with the admin key: --from admin. See Rotate as the admin.
3. Wait for the validator set to switch
The chain’s state swaps immediately, sosimd q poa validators shows the new key in the same block the transaction lands. CometBFT applies the actual validator set change two blocks later, and only that switch governs when the node must sign with the new key. Until it happens, CometBFT still expects the old key, so keep the live node running untouched. Watch the CometBFT validator set until the new consensus key appears and the old one is gone:
simd comet show-validator --home ~/.poa-newkey. Confirm the module re-keyed with simd q poa validators.
Do not swap the node’s key before the set switches (wait at least 2 blocks). Swapping early makes the node sign with a key CometBFT does not yet expect, and the validator misses blocks. Running two nodes that hold this validator’s signing keys at the same time risks a double sign. Never run more than one active signer for the validator.
4. Swap the node’s key
Once the new consensus address is in the set, stop the node, replace its key, and restart:A validator with power 0 is outside the active set. Its rotation emits no validator set update, so there is no transition to time. Swap the node’s key first, then have the admin grant power.
Rotate as the admin
The admin rotates any validator’s key with the same command, signed by the admin key.Verify
The rotation emits an event with the operator address, the old consensus address, and the new one. Confirm the set carries the new consensus address and the node is signing:What can go wrong
- The transaction is rejected as unauthorized: the signer is neither the validator’s operator nor the admin.
- The transaction is rejected for the key itself: the new key equals the current one, is already used by another validator, or its type is not in the chain’s consensus params.
- The validator misses blocks right after the swap: the node’s key was replaced before the set switched. Restore the old key, wait for the set, then swap again.
- The validator goes dark after an admin rotation: the node still holds the old key. Swap
priv_validator_key.jsonand restart.
Next steps
- Rotate to a post-quantum key. See Migrate a validator to ML-DSA.
- Understand the mechanics and the staking differences. See Key rotation.
- Look up the message. See the PoA API reference.