How to update KES key to an active running pool?

We all know that we need to update KES key periodically on the mainnet. However I don’t find an authorative description for this process. Here is my understanding. Can someone confirm so that we are sure we are not missing anything?

  • create a new pair of kes key (kes.skey, kes.vkey)
    cardano-cli node key-gen-KES \
        --verification-key-file kes.vkey \
        --signing-key-file kes.skey
  • re-generate node certificate
    cardano-cli node issue-op-cert \
        --kes-verification-key-file kes.vkey \
        --cold-signing-key-file node.skey \
        --operational-certificate-issue-counter node.counter \
        --kes-period  ${startKesPeriod}\
        --out-file node.cert
  • copy all 3 files over to producer node and restart cardano-node service.


Seems alright.
this gives you the startKesPeriod and has to be run on online synced note = not the one where you keep your node.skey and node.counter

slotsPerKESPeriod=$(cat NODE_HOME/{NODE_CONFIG}-shelley-genesis.json | jq -r ‘.slotsPerKESPeriod’)

slotNo=$(cardano-cli query tip --mainnet | jq -r ‘.slot’)

startKesPeriod=(({slotNo} / ${slotsPerKESPeriod}))


yes, once you have the KesPeriod as @Triton-pool suggest you are good to go, here is the description for this process from Cardano project site:

any idea why Guide: How to build a Cardano Stake Pool - CoinCashew says only copy the new node.cert but not the new kes.skey?

Because kes.skey is already there.

But in their example they generate a new pair:
“Make a new KES key pair.”

When the node says “cardano_node_metrics_remainingKESPeriods_int=62” is that a proof that the rotation went well?

Yes, is it correct ; also u should see in glive the new expiration date

62x1.5=93 days

Actually my understanding is that when you do the KES rotation , you can keep the KES pair but generate the node.cert using the current KES period , am I correct ?

You can, and I’ve tried that in the past on testnets. However there might be a limited number of time one can do that. Regenerating the KES pair is not so much of an extra to justify skipping it in the end.

No. My understanding is that you must generate a new pair of KES key. Below is an excerpt from cardano webiste:

Unfortunately, there is a catch: A KES key can only evolve for a certain number of periods and becomes useless afterwards. This means that before that number of periods has passed, the node operator has to generate a new KES key pair, issue a new operational node certificate with that new key pair and restart the node with the new certificate.

Below is the script I use to update KES key and node certificate.

    slotsPerKESPeriod=$(cat ${NETWORK}-shelley-genesis.json | jq -r '.slotsPerKESPeriod')
    echo slotsPerKESPeriod: ${slotsPerKESPeriod}
    slotNo=$(cardano-cli query tip ${NETWORK_MAGIC} | jq -r '.slot')
    echo slotNo: ${slotNo}

    kesPeriod=$((${slotNo} / ${slotsPerKESPeriod}))
    echo kesPeriod: ${kesPeriod}
    echo startKesPeriod: ${startKesPeriod}

    # back up if needed
    local today=$(date +"%Y%m%d")
    local backdir="BACKUP/$today"
    if [[ ! -d $backdir ]]; then
        echo "backup KES key and node cert ..."
        mkdir -p $backdir
        cp -f kes.vkey $backdir/
        cp -f kes.skey $backdir/
        cp -f node.cert $backdir/

    echo "generate new KES key ..."
    cardano-cli node key-gen-KES \
        --verification-key-file kes.vkey \
        --signing-key-file kes.skey

    # gen node certificate
    echo "create node certificate ..."
    cardano-cli node issue-op-cert \
        --kes-verification-key-file kes.vkey \
        --cold-signing-key-file node.skey \
        --operational-certificate-issue-counter node.counter \
        --kes-period  ${startKesPeriod}\
        --out-file node.cert

    echo copy over new key and restart cardano service ...
    scp_to producer node.cert ""
    scp_to producer kes.skey ""
    scp_to producer kes.vkey ""

    ssh_run producer "sudo systemctl restart cardano-producer"
    ssh_run producer "sudo systemctl status cardano-producer"

I have not had to rotate/update my KES yet, but isnt it easier to use ?

cant figure out where im going wrong with the kes rotation… Created new key pair on Block producer, copied kes.vkey to cold enviroment and created a new node.cert with the current kes period… block producer stuck starting with kes current/remaining at 0/0 with todays date as the expiration. Any help would be greatly appreciated.

journalctl -e -f -u cardano-node

Nov 02 00:47:37 node cardano-node[134928]: [node:cardano.node.Forge:Error:229] [2021-11-02 00:47:37.00 UTC] fromList [(“val”,Object (fromList [(“kind”,String “TraceNoLedgerView”),(“slot”,Number 4.4247766e7)])),(“credentials”,String “Cardano”)]

Nov 02 00:47:38 node cardano-node[134928]: [node:cardano.node.LeadershipCheck:Info:229] [2021-11-02 00:47:38.00 UTC] {“kind”:“TraceStartLeadershipCheck”,“chainDensity”:5.0e-2,“slot”:44247767,“delegMapSize”:913114,“utxoSize”:3759243,“credentials”:“Cardano”}

Nov 02 00:47:38 node cardano-node[134928]: [node:cardano.node.Forge:Error:229] [2021-11-02 00:47:38.00 UTC] fromList [(“val”,Object (fromList [(“kind”,String “TraceNoLedgerView”),(“slot”,Number 4.4247767e7)])),(“credentials”,String “Cardano”)]

ok, try to restart the node

sudo systemctl restart cardano-node
journalctl -e -f -u cardano-node and share the output (including the restart timestamp … stop/starting)

Logs begin at Mon 2021-10-18 04:05:46 UTC. –

Nov 02 00:39:19 node cardano-node[134928]: [node:cardano.node.Forge:Error:229] [2021-11-02 00:39:19.00 UTC] fromList [(“val”,Object (fromList [(“kind”,String “TraceNoLedgerView”),(“slot”,Number 4.4247268e7)])),(“credentials”,String “Cardano”)]

Nov 02 00:39:20 node cardano-node[134928]: [node:cardano.node.LeadershipCheck:Info:229] [2021-11-02 00:39:20.00 UTC] {“kind”:“TraceStartLeadershipCheck”,“chainDensity”:5.0e-2,“slot”:44247269,“delegMapSize”:913114,“utxoSize”:3759243,“credentials”:“Cardano”}

Nov 02 00:59:29 node cardano-node[190911]: [node:cardano.node.ChainDB:Info:5] [2021-11-02 00:59:29.57 UTC] Replayed block: slot SlotNo 43329608 of At (SlotNo 43329608)
Nov 02 00:59:29 node cardano-node[190911]: [node:cardano.node.ChainDB:Info:5] [2021-11-02 00:59:29.57 UTC] Opened lgr db

no man, I meant to share the output after you will restart the node… not the old logs

this is after i restarted the node.

nothing with starting or listening?