We're running the NPoS chain with Aura, Grandpa instead of Babe.

We've just upgraded our solochain. In this upgrade, we changed pallet_election_provider_multi_phase::Config::Fallback=BoundedExecution instead of NoFallback.

Due to unfortunate incident while upgrading, the chain stopped producing blocks. However, after solving the incident, the chain continues as normal (thanks to Aura, this is the reason why we choose Aura instead of Babe in the first place). And we know for sure that the staking election will fail because we've encountered this problem before because of the same incident. Back then NoFallback is used, the chain stopped working until we solve it by submit election solution through setEmergencyElectionResult (thanks to the documentation here).

In the new upgrade, we use BoundedExecution as in this pull request. BoundedExecution fallback helps the chain to continue to function even when the staking.StakingElectionFailed.

My question is: Can we bring the staking election back to normal instead of relying on BoundedExecution fallback?


[1840200] 💸 generated 0 npos voters, 0 from validators and 0 nominators
[#1840200] 🗳 Finalized election round with compute Fallback.
[1840200] 💸 chain does not have enough staking candidates to operate for era 1530 (0 elected, minimum is 3)

2 Answers 2


For anyone who may encounter this problem here is the solution and also the explanation.


You may encounter this problem when update older substrate version to the newer one. In my case, it is from substrate polkadot-v0.9.18 to substrate polkadot-v0.9.23.

Tks to @kianenigma suggestion, I've looked into the implementation of pallet_staking::get_npos_voters() and found that there is a difference in implementation between older and newer version.

In older version, pallet_staking::get_npos_voters() use its Validators and Nominators storage items to return the voters. While in newer version, pallet_staking::get_npos_voters() use T::VoterList (which is usually configured to be pallet_bags_list) to return the voters.

When we validate/nominate, our votes are not recorded in T::VoterList in older implementation while newer implementation already does. And when we switch to the new version, T::VoterList is empty. That's why staking election always failed.


The solution is to chill your nominators/validators, and validate/nominate again so that new implementation will record your votes in T::VoterList. And maybe forceNewEra() using sudo account. Maybe re-try a couple of times until you see staking.Elected.


generated 0 npos voters, 0 from validators and 0 nominators

Your logs are indicating that your chain has no nominators (voters), and no validators either, this is the root cause of the issue.

Otherwise, your steps in using a proper fallback is correct.

  • There are already validators. But the staking election is still failed :(. Can you check this, please? apps.bholdus.com/…. The log from the node still says 0 validators
    – Daniel Lam
    Jun 16, 2022 at 15:37
  • Do you have subscan or some explorer where I can see the details of the blocks in which the election has failed? It does seem like you have 3 validators, but no nominators, and you election process seems fine to me.
    – kianenigma
    Jun 16, 2022 at 16:28
  • In whichever version of substrate you are, you should look into the get_npos_voters function and try and map that to your chain data to try and figure out what is going wrong. Also, it would help if you paste a link to your actual runtime configs.
    – kianenigma
    Jun 16, 2022 at 16:30
  • just check get_npos_voters() implementation. From on-chain state, there are 3 validators, but in the end of get_npos_voters(), all_voters is 0. @kianenigma
    – Daniel Lam
    Jun 17, 2022 at 3:49
  • It could be the T::VoterList::count() returns 0. In the older version of substrate, all_voters is calculated from Validators::count() and Nominators::count(). I think this is the reason why the election always says that 0 validators in the new substrate version. @kianenigma
    – Daniel Lam
    Jun 17, 2022 at 6:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.