hyperledger/fabric · error

Invalid new config: the number of bft consenters: %d is not

Error message

Invalid new config: the number of bft consenters: %d is not equal to the number of raft consenters: %d

What it means

For a Raft-to-BFT migration, the number of consenters in the new BFT config must exactly match the number of consenters in the current Raft metadata. A mismatch would add or drop ordering nodes mid-migration, which the migration procedure forbids.

Source

Thrown at orderer/common/msgprocessor/maintenancefilter.go:226

	return nil
}

func validateBFTConsenterMapping(currentOrdererConfig channelconfig.Orderer, nextOrdererConfig channelconfig.Orderer) error {
	// extract raft consenters from consensusTypeValue.metadata
	raftMetadata := &etcdraft.ConfigMetadata{}
	proto.Unmarshal(currentOrdererConfig.ConsensusMetadata(), raftMetadata)
	raftConsenters := raftMetadata.GetConsenters()

	// extract bft consenters
	bftConsenters := nextOrdererConfig.Consenters()

	if len(bftConsenters) == 0 {
		return errors.Errorf("Invalid new config: bft consenters are missing")
	}

	if len(raftConsenters) != len(bftConsenters) {
		return errors.Errorf("Invalid new config: the number of bft consenters: %d is not equal to the number of raft consenters: %d", len(bftConsenters), len(raftConsenters))
	}

	for _, raftConsenter := range raftConsenters {
		flag := false
		for _, bftConsenter := range bftConsenters {
			if raftConsenter.Port == bftConsenter.Port && raftConsenter.Host == bftConsenter.Host &&
				bytes.Equal(raftConsenter.ServerTlsCert, bftConsenter.ServerTlsCert) &&
				bytes.Equal(raftConsenter.ClientTlsCert, bftConsenter.ClientTlsCert) {
				flag = true
				break
			}
		}
		if !flag {
			return errors.Errorf("No suitable BFT consenter for Raft consenter: %v", raftConsenter)
		}
	}

	return nil

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Adjust the BFT consenters list so it contains exactly the same number of entries (same nodes) as the current Raft consenters.
  2. Perform any node addition/removal as a separate config step outside the consensus-type migration.
  3. Diff both consenter lists before submitting to confirm equal counts.

Example fix

// before
// raft: 4 consenters, bft metadata: 3 consenters
// after
// bft Consenters array padded to the same 4 nodes as raft metadata
Defensive patterns

Strategy: validation

Validate before calling

raftCount := len(currentRaftMetadata.GetConsenters())
bftCount := len(newMetadata.GetConsenters())
if raftCount != bftCount {
    return fmt.Errorf("consenter count mismatch: raft=%d bft=%d", raftCount, bftCount)
}

Prevention

When it happens

Trigger: validateBFTConsenterMapping finds len(raftMetadata consenters) != len(nextOrdererConfig.Consenters()) — e.g. the proposed BFT metadata lists a different count of nodes than the current etcdraft metadata.

Common situations: Admins using migration as an opportunity to scale the ordering service up or down; forgetting that node additions/removals must be done separately (before or after migration, via channel reconfiguration).

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/f63a5e1ac7795556. Report an issue: GitHub.