hyperledger/fabric · error

cannot load consenter config for orderer type %s: %s

Error message

cannot load consenter config for orderer type %s: %s

What it means

For BFT orderers, NewOrdererGroup converts conf.ConsenterMapping into consenter protobufs via consenterProtosFromConfig. Failure there (bad host/port, unreadable cert/identity files) is wrapped as 'cannot load consenter config for orderer type BFT'. It stops the config group from being built before the Orderers value and BFT metadata are added.

Source

Thrown at internal/configtxgen/encoder/encoder.go:221

	addValue(ordererGroup, channelconfig.ChannelRestrictionsValue(conf.MaxChannels), channelconfig.AdminsPolicyKey)

	if len(conf.Capabilities) > 0 {
		addValue(ordererGroup, channelconfig.CapabilitiesValue(conf.Capabilities), channelconfig.AdminsPolicyKey)
	}

	var consensusMetadata []byte
	var err error

	switch conf.OrdererType {
	case ConsensusTypeSolo:
	case ConsensusTypeEtcdRaft:
		if consensusMetadata, err = channelconfig.MarshalEtcdRaftMetadata(conf.EtcdRaft); err != nil {
			return nil, errors.Errorf("cannot marshal metadata for orderer type %s: %s", ConsensusTypeEtcdRaft, err)
		}
	case ConsensusTypeBFT:
		consenterProtos, err := consenterProtosFromConfig(conf.ConsenterMapping)
		if err != nil {
			return nil, errors.Errorf("cannot load consenter config for orderer type %s: %s", ConsensusTypeBFT, err)
		}
		addValue(ordererGroup, channelconfig.OrderersValue(consenterProtos), channelconfig.AdminsPolicyKey)
		if consensusMetadata, err = channelconfig.MarshalBFTOptions(conf.SmartBFT); err != nil {
			return nil, errors.Errorf("consenter options read failed with error %s for orderer type %s", err, ConsensusTypeBFT)
		}
		// Force leader rotation to be turned off
		conf.SmartBFT.LeaderRotation = smartbft.Options_ROTATION_OFF
		// Overwrite policy manually by computing it from the consenters
		policies.EncodeBFTBlockVerificationPolicy(consenterProtos, ordererGroup)
	default:
		return nil, errors.Errorf("unknown orderer type: %s", conf.OrdererType)
	}

	addValue(ordererGroup, channelconfig.ConsensusTypeValue(conf.OrdererType, consensusMetadata), channelconfig.AdminsPolicyKey)

	for _, org := range conf.Organizations {
		var err error
		ordererGroup.Groups[org.Name], err = NewOrdererOrgGroup(org, channelCapabilities)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Inspect the wrapped underlying error — it names the failing consenter host:port and cause
  2. Verify each ConsenterMapping entry's Identity/ClientTLSCert/ServerTLSCert files exist and are valid PEM
  3. Run configtxgen from the directory where relative cert paths resolve, or use absolute paths
  4. Check Host/Port are non-empty and numeric where required

Example fix

# before
ConsenterMapping:
    - Identity: crypto/badpath/id.pem
      Host: orderer.example.com
      Port: 7050
# after
ConsenterMapping:
    - Identity: crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp/signcerts/orderer-example-com-cert.pem
      ClientTLSCert: crypto-config/.../tls/server.crt
      ServerTLSCert: crypto-config/.../tls/server.crt
      Host: orderer.example.com
      Port: 7050
Defensive patterns

Strategy: validation

Validate before calling

func validateBFTConsenters(conf *genesisconfig.Orderer) error {
    for _, c := range conf.ConsenterMapping {
        for _, p := range []string{c.Identity, c.ClientTLSCert, c.ServerTLSCert} {
            if p != "" {
                if _, err := os.ReadFile(p); err != nil { return fmt.Errorf("consenter %s:%d: %w", c.Host, c.Port, err) }
            }
        }
        if c.Host == "" || c.Port == 0 { return fmt.Errorf("consenter host/port invalid") }
    }
    return nil
}

Type guard

func hasBFTConsenterMapping(conf *genesisconfig.Orderer) bool { return conf.OrdererType == "BFT" && len(conf.ConsenterMapping) > 0 }

Try / catch

group, err := encoder.NewOrdererGroup(conf, caps)
if err != nil && strings.Contains(err.Error(), "cannot load consenter config") {
    return fmt.Errorf("check ConsenterMapping cert/identity paths: %w", err)
}

Prevention

When it happens

Trigger: NewOrdererGroup with OrdererType "BFT" where consenterProtosFromConfig returns an error: a ConsenterMapping entry has an invalid address or a ClientTLSCert/ServerTLSCert/Identity path that cannot be read/parsed.

Common situations: Migrating a profile from etcdraft to BFT: consenter entries reference cert files that were never generated, wrong relative paths when running configtxgen from another directory, or malformed host/port strings.

Related errors


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