hyperledger/fabric · error
not a SmartBFT config block
Error message
not a SmartBFT config block
What it means
IsConsenterOfChannel only validates consenters for channels configured with consensus type BFT (Smart BFT). If the bundle's orderer config reports a different ConsensusType (e.g. etcdraft, solo), the block cannot be interpreted as a SmartBFT config and this error is returned.
Source
Thrown at orderer/consensus/smartbft/util.go:413
// It returns nil if true, else returns an error.
func (conCert ConsenterCertificate) IsConsenterOfChannel(configBlock *cb.Block) error {
if configBlock == nil {
return errors.New("nil block")
}
envelopeConfig, err := protoutil.ExtractEnvelope(configBlock, 0)
if err != nil {
return err
}
bundle, err := channelconfig.NewBundleFromEnvelope(envelopeConfig, conCert.CryptoProvider)
if err != nil {
return err
}
oc, exists := bundle.OrdererConfig()
if !exists {
return errors.New("no orderer config in bundle")
}
if oc.ConsensusType() != "BFT" {
return errors.New("not a SmartBFT config block")
}
for _, consenter := range oc.Consenters() {
if bytes.Equal(conCert.ConsenterCertificate, consenter.ServerTlsCert) || bytes.Equal(conCert.ConsenterCertificate, consenter.ClientTlsCert) {
return nil
}
}
return cluster.ErrNotInChannel
}
type worker struct {
work [][]byte
f func([]byte)
workerNum int
id int
}
func (w *worker) doWork() {View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure the channel's consensus.type is set to BFT in configtx.yaml and regenerate/commit the config block
- Point IsConsenterOfChannel at a config block belonging to a BFT channel
- If the channel should stay etcdraft, use the etcdraft cluster check instead of the SmartBFT one
Example fix
// configtx.yaml Orderer: OrdererType: etcdraft // after Orderer: OrdererType: BFT
Defensive patterns
Strategy: validation
Validate before calling
bundle, _ := channelconfig.NewBundleFromEnvelope(env, cryptoProvider)
oc, ok := bundle.OrdererConfig()
if ok && oc.ConsensusType() != "BFT" {
return errors.Errorf("channel consensus is %s, not BFT", oc.ConsensusType())
} Type guard
func isBFTChannel(oc channelconfig.Orderer) bool {
return oc.ConsensusType() == "BFT"
} Try / catch
if err := IsConsenterOfChannel(env, cert); err != nil {
if strings.Contains(err.Error(), "not a SmartBFT config block") {
// route to the appropriate consensus-type checker
}
} Prevention
- Set OrdererType: BFT in configtx.yaml for SmartBFT channels
- Keep track of which channels use etcdraft vs BFT
- Re-fetch the latest config block after consensus-type migration
When it happens
Trigger: Calling IsConsenterOfChannel on a channel whose orderer group has ConsensusType other than "BFT" — e.g. an etcdraft channel — while the caller expects SmartBFT.
Common situations: Mixed-consensus network where a SmartBFT node receives an etcdraft channel's config block; migrating channels between consensus types but pointing at stale blocks; misconfigured configtx.yaml consensus.type.
Related errors
- failed to unmarshal BFT metadata configuration
- invalid BFT metadata configuration
- invalid BFT consenter mapping configuration
- failed getting a new bundle from envelope of config block
- no orderer config in config block
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/b9af12b37c0994e8.
Report an issue: GitHub.