hyperledger/fabric · critical
etcdraft options have not been provided
Error message
etcdraft options have not been provided
What it means
HandleChain (orderer/consensus/etcdraft/consenter.go:126) requires etcdraft Options (TickInterval, ElectionTick, HeartbeatTick, MaxInflightMsgs, SnapshotInterval) to be present in the channel's consensus metadata. If the unmarshaled ConfigMetadata has no Options field, the chain cannot be configured and this error is returned. It indicates an incomplete etcdraft configuration in the channel config.
Source
Thrown at orderer/consensus/etcdraft/consenter.go:126
if crypto.CertificatesWithSamePublicKey(thisNodeCertAsDER, certAsDER) == nil {
return nodeID, nil
}
}
c.Logger.Warning("Could not find", string(c.Cert), "among", serverCertificates)
return 0, cluster.ErrNotInChannel
}
// HandleChain returns a new Chain instance or an error upon failure
func (c *Consenter) HandleChain(support consensus.ConsenterSupport, metadata *common.Metadata) (consensus.Chain, error) {
m := &etcdraft.ConfigMetadata{}
if err := proto.Unmarshal(support.SharedConfig().ConsensusMetadata(), m); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal consensus metadata")
}
if m.GetOptions() == nil {
return nil, errors.New("etcdraft options have not been provided")
}
isMigration := (metadata == nil || len(metadata.GetValue()) == 0) && (support.Height() > 1)
if isMigration {
c.Logger.Debugf("Block metadata is nil at block height=%d, it is consensus-type migration", support.Height())
}
// determine raft replica set mapping for each node to its id
// for newly started chain we need to read and initialize raft
// metadata by creating mapping between conseter and its id.
// In case chain has been restarted we restore raft metadata
// information from the recently committed block meta data
// field.
blockMetadata, err := ReadBlockMetadata(metadata, m)
if err != nil {
return nil, errors.Wrapf(err, "failed to read Raft metadata")
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Regenerate the genesis/config metadata including Options (TickInterval, ElectionTick, HeartbeatTick, MaxInflightMsgs, SnapshotInterval) via configtxgen
- Add the missing Options block to the channel config and resubmit via config update if channel already exists
- Use a Fabric version-matched sample configtx.yaml Orderer.EtcdRaft.Options section as template
Example fix
// before
ConfigMetadata{Consenters: [...]} // Options omitted
// after
ConfigMetadata{Consenters: [...], Options: &etcdraft.Options{TickInterval: "500ms", ElectionTick: 10, HeartbeatTick: 1, MaxInflightMsgs: 256, SnapshotInterval: 4194304}} Defensive patterns
Strategy: validation
Validate before calling
m := &etcdraft.ConfigMetadata{}
if err := proto.Unmarshal(raw, m); err != nil { return err }
if m.GetOptions() == nil {
return errors.New("ConfigMetadata.Options is required (TickInterval, ticks, SnapshotInterval, MaxInflightMsgs)")
} Type guard
func hasRaftOptions(m *etcdraft.ConfigMetadata) bool {
o := m.GetOptions()
return o != nil && o.GetTickInterval() != "" && o.GetElectionTick() > 0 && o.GetHeartbeatTick() > 0
} Prevention
- Start from the sample Orderer.EtcdRaft section in configtx.yaml
- Never strip Options when regenerating metadata
- Test genesis blocks with configtxgen before deploying
When it happens
Trigger: A channel is configured with consensus type etcdraft but its ConfigMetadata proto lacks the Options field (nil Options), detected during orderer chain startup.
Common situations: Hand-built genesis config that populated Consenters but omitted Options; a migration to etcdraft whose metadata template was incomplete; tooling that zeroed Options when rewriting metadata.
Related errors
- failed to unmarshal consensus metadata
- failed to parse TickInterval (%s) to time duration
- chaincode type not supported: %s
- failed to copy metadataDir directory folder: %s
- error unmarshalling YAML file %s: %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/c706d92f919ab319.
Report an issue: GitHub.