hyperledger/fabric · error

No suitable BFT consenter for Raft consenter: %v

Error message

No suitable BFT consenter for Raft consenter: %v

What it means

After count-checking, each Raft consenter must have a matching BFT consenter identified by identical Host, Port, and TLS certificates. If some Raft consenter has no corresponding BFT entry, the migration is rejected because node identities must be preserved across the consensus-type change.

Source

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

		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. Ensure each BFT consenter entry has the exact same Host, Port, and ClientTlsCert bytes as the corresponding Raft consenter.
  2. Defer TLS certificate rotation to a separate config update after migration completes.
  3. Regenerate the BFT metadata by copying the Raft consenter list verbatim and only changing the consensus type fields.

Example fix

// before
// bft consenter: {Host: "node1.example.com", Port: 7050, ClientTlsCert: newCert}
// after
// bft consenter: {Host: "node1.example.com", Port: 7050, ClientTlsCert: raftClientCert}
Defensive patterns

Strategy: validation

Validate before calling

for _, r := range raftConsenters {
    found := false
    for _, b := range bftConsenters {
        if r.Host == b.Host && r.Port == b.Port && bytes.Equal(r.ClientTlsCert, b.ClientTlsCert) {
            found = true
            break
        }
    }
    if !found {
        return fmt.Errorf("no matching BFT consenter for %s:%d", r.Host, r.Port)
    }
}

Prevention

When it happens

Trigger: validateBFTConsenterMapping iterates raftConsenters and finds one whose (Host, Port, ClientTlsCert) tuple does not match any entry in the proposed BFT consenters list — even if the counts are equal.

Common situations: Rotating TLS certificates as part of the migration update (certs must match the current Raft certs at migration time); typos in hostnames or ports; reordering entries while a cert pair is mismatched.

Related errors


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