hyperledger/fabric · error

consenter options read failed with error %s for orderer type

Error message

consenter options read failed with error %s for orderer type %s

What it means

For BFT orderers, after loading consenters the encoder marshals conf.SmartBFT (the smartbft.Options proto) into consensus metadata via channelconfig.MarshalBFTOptions. If those options are invalid or cannot be serialized, NewOrdererGroup returns this message embedding the marshal error and the BFT orderer type.

Source

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

	}

	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)
		if err != nil {
			return nil, errors.Wrap(err, "failed to create orderer org")
		}
	}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Read the embedded error after 'error' — it identifies which SmartBFT option failed
  2. Compare your SmartBFT block against the Fabric BFT sample configtx.yaml and fix field names/values
  3. If options are set programmatically, validate the smartbft.Options proto before calling the encoder
  4. Regenerate the genesis/channel config once options are corrected

Example fix

# before
SmartBFT:
    RequestBatchMaxCount: "not-a-number"
# after
SmartBFT:
    RequestBatchMaxCount: 100
    RequestBatchMaxInterval: 50ms
    LeaderRotation: 0
Defensive patterns

Strategy: validation

Validate before calling

func validateSmartBFTOptions(opts *smartbft.Options) error {
    if opts == nil { return errors.New("SmartBFT options required for BFT orderer") }
    if opts.RequestBatchMaxCount <= 0 { return errors.New("RequestBatchMaxCount must be positive") }
    return nil
}

Type guard

func hasSmartBFT(conf *genesisconfig.Orderer) bool { return conf.OrdererType == "BFT" && conf.SmartBFT != nil }

Try / catch

group, err := encoder.NewOrdererGroup(conf, caps)
if err != nil && strings.Contains(err.Error(), "consenter options read failed") {
    return fmt.Errorf("fix SmartBFT options block in configtx.yaml: %w", err)
}

Prevention

When it happens

Trigger: NewOrdererGroup/NewChannelGroup with OrdererType "BFT" where MarshalBFTOptions(conf.SmartBFT) fails — e.g. malformed/missing SmartBFT fields in configtx.yaml (request batch timeouts, leader rotation settings, incorrect numeric values).

Common situations: Hand-editing the SmartBFT section with wrong field names/types, leaving required options unset, or reusing an etcdraft profile body under a BFT OrdererType.

Related errors


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