hyperledger/fabric · error
nil Raft config metadata
Error message
nil Raft config metadata
What it means
VerifyConfigMetadata validates a Raft ConfigMetadata proto. It returns this error when the metadata pointer itself is nil. The comment marks it as defensive: CheckConfigMetadata/metadata construction should never produce a nil ConfigMetadata, so reaching this indicates a programming or decoding failure upstream.
Source
Thrown at orderer/consensus/etcdraft/util.go:210
if err != nil {
return nil, nil, errors.Wrap(err, "failed to extract payload from config envelope")
}
// get config update
configUpdate, err := configtx.UnmarshalConfigUpdateFromPayload(payload)
if err != nil {
return nil, nil, errors.Wrap(err, "could not read config update")
}
return MetadataFromConfigUpdate(configUpdate)
}
// VerifyConfigMetadata validates Raft config metadata.
// Note: ignores certificates expiration.
func VerifyConfigMetadata(metadata *etcdraft.ConfigMetadata, verifyOpts x509.VerifyOptions) error {
if metadata == nil {
// defensive check. this should not happen as CheckConfigMetadata
// should always be called with non-nil config metadata
return errors.Errorf("nil Raft config metadata")
}
if metadata.GetOptions() == nil {
return errors.Errorf("nil Raft config metadata options")
}
if metadata.GetOptions().GetHeartbeatTick() == 0 ||
metadata.GetOptions().GetElectionTick() == 0 ||
metadata.GetOptions().GetMaxInflightBlocks() == 0 {
// if SnapshotIntervalSize is zero, DefaultSnapshotIntervalSize is used
return errors.Errorf("none of HeartbeatTick (%d), ElectionTick (%d) and MaxInflightBlocks (%d) can be zero",
metadata.GetOptions().GetHeartbeatTick(), metadata.GetOptions().GetElectionTick(), metadata.GetOptions().GetMaxInflightBlocks())
}
// check Raft options
if metadata.GetOptions().GetElectionTick() <= metadata.GetOptions().GetHeartbeatTick() {
return errors.Errorf("ElectionTick (%d) must be greater than HeartbeatTick (%d)",
metadata.GetOptions().GetElectionTick(), metadata.GetOptions().GetHeartbeatTick())View on GitHub (pinned to 2736b63f8f)
Solutions
- Check that the value passed is a non-nil *etcdraft.ConfigMetadata before calling VerifyConfigMetadata.
- Confirm the channel config's ConsensusType.Metadata was unmarshalled into etcdraft.ConfigMetadata (not raw bytes).
- If metadata comes from a config update, ensure MetadataFromConfigUpdate succeeded without error.
Example fix
// before
err := VerifyConfigMetadata(meta, opts)
// after
if meta == nil { return errors.New("missing raft config metadata") }
err := VerifyConfigMetadata(meta, opts) Defensive patterns
Strategy: type-guard
Validate before calling
if metadata == nil {
return errors.New("raft config metadata not extracted; check ConsensusType in channel config")
} Type guard
func hasRaftMetadata(m *etcdraft.ConfigMetadata) bool { return m != nil } Try / catch
if err := VerifyConfigMetadata(meta, opts); err != nil {
if strings.Contains(err.Error(), "nil Raft config metadata") {
return errors.New("metadata missing entirely - not a raft channel?")
}
return err
} Prevention
- Never call VerifyConfigMetadata on results of failed metadata extraction.
- Check the channel's consensus type is etcdraft before raft-specific validation.
- Fail fast when Unmarshal of ConsensusType.Metadata returns nil.
When it happens
Trigger: Calling VerifyConfigMetadata(nil, opts) directly, or passing metadata extracted from a config update whose ConsensusType.Metadata failed to decode into etcdraft.ConfigMetadata.
Common situations: Unit tests calling with nil; channel config where consensus_type metadata is empty bytes; unmarshalling skipped but nil result propagated.
Related errors
- config envelope is nil
- Invalid signed proposal during channelless check policy with
- nil Raft config metadata options
- none of HeartbeatTick (%d), ElectionTick (%d) and MaxInfligh
- ElectionTick (%d) must be greater than HeartbeatTick (%d)
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/ce5f59d14a61aad5.
Report an issue: GitHub.