hyperledger/fabric · error
no orderer config in bundle
Error message
no orderer config in bundle
What it means
IsConsenterOfChannel builds a channelconfig.Bundle from the config envelope and then reads the orderer configuration section. If the bundle has no OrdererConfig (bundle.OrdererConfig() returns exists=false), the block is not a valid channel config for an ordering system channel, so the check cannot proceed and this error is returned.
Source
Thrown at orderer/consensus/etcdraft/util.go:375
// IsConsenterOfChannel returns whether the caller is a consenter of a channel
// by inspecting the given configuration block.
// It returns nil if true, else returns an error.
func (conCert ConsenterCertificate) IsConsenterOfChannel(configBlock *common.Block) error {
if configBlock == nil || configBlock.GetHeader() == nil {
return errors.New("nil block or nil header")
}
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")
}
m := &etcdraft.ConfigMetadata{}
if err := proto.Unmarshal(oc.ConsensusMetadata(), m); err != nil {
return err
}
bl, _ := pem.Decode(conCert.ConsenterCertificate)
if bl == nil {
return errors.Errorf("my consenter certificate %s is not a valid PEM", string(conCert.ConsenterCertificate))
}
myCertDER := bl.Bytes
var failedMatches []string
for _, consenter := range m.GetConsenters() {
candidateBlock, _ := pem.Decode(consenter.GetServerTlsCert())
if candidateBlock == nil {
return errors.Errorf("candidate server certificate %s is not a valid PEM", string(consenter.GetServerTlsCert()))View on GitHub (pinned to 2736b63f8f)
Solutions
- Pass the correct config block — the ordering system channel's config block, not an application channel block
- Regenerate genesis/config with an Orderer section defined in configtx.yaml (Orderer: OrdererType, Organizations, etc.)
- Verify the block is actually a CONFIG block (type HeaderType_CONFIG) with a valid orderer config group
Example fix
// before
err := conCert.IsConsenterOfChannel(appChannelBlock) // app channel, no orderer config
// after
configBlock, err := cluster.RetrieveSystemChannelConfigBlock(ledger)
if err != nil { return err }
err = conCert.IsConsenterOfChannel(configBlock) Defensive patterns
Strategy: validation
Validate before calling
envelopeConfig, err := protoutil.ExtractEnvelope(configBlock, 0)
if err != nil { return err }
bundle, err := channelconfig.NewBundleFromEnvelope(envelopeConfig, cryptoProvider)
if err != nil { return err }
if bundle.OrdererConfig() == nil {
return errors.New("block has no orderer config; expected system channel config block")
} Prevention
- Verify the block type is HeaderType_CONFIG and from the ordering system channel
- Ensure configtx.yaml defines an Orderer section before generating genesis
- Validate config blocks with channelconfig.NewBundleFromEnvelope in CI before deployment
When it happens
Trigger: Calling IsConsenterOfChannel with a config block whose embedded config envelope lacks the orderer group — e.g. an application channel block or a malformed config passed as the config block.
Common situations: Passing a regular application-channel block where a config block of the ordering system channel is expected; channel config created without an Orderer section in configtx.yaml; corrupted or hand-edited config block envelope.
Related errors
- OrdererOrg config does not allow sub-groups
- [channel %s] cannot create channel because ChannelConfig is
- no orderer section in channel config for channel [%s].
- no policies in config block
- no orderer section in config block
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/9d3a6f8cf3133e0c.
Report an issue: GitHub.