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

  1. Pass the correct config block — the ordering system channel's config block, not an application channel block
  2. Regenerate genesis/config with an Orderer section defined in configtx.yaml (Orderer: OrdererType, Organizations, etc.)
  3. 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

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


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