hyperledger/fabric · error
nil metadata
Error message
nil metadata
What it means
MetadataHasDuplication validates the etcdraft ConfigMetadata carried in a channel config update. It returns this error immediately when the metadata pointer itself is nil, since there are no consenters to validate at all. Callers use it via VerifyConfigMetadata to reject malformed config updates before they are committed.
Source
Thrown at orderer/consensus/etcdraft/util.go:62
_, exists := c[string(consenter.GetClientTlsCert())]
return exists
}
// ConsentersToMap maps consenters into set where key is client TLS certificate
func ConsentersToMap(consenters []*etcdraft.Consenter) ConsentersMap {
set := map[string]struct{}{}
for _, c := range consenters {
set[string(c.GetClientTlsCert())] = struct{}{}
}
return set
}
// MetadataHasDuplication returns an error if the metadata has duplication of consenters.
// A duplication is defined by having a server or a client TLS certificate that is found
// in two different consenters, regardless of the type of certificate (client/server).
func MetadataHasDuplication(md *etcdraft.ConfigMetadata) error {
if md == nil {
return errors.New("nil metadata")
}
for _, consenter := range md.GetConsenters() {
if consenter == nil {
return errors.New("nil consenter in metadata")
}
}
seen := make(map[string]struct{})
for _, consenter := range md.GetConsenters() {
serverKey := string(consenter.GetServerTlsCert())
clientKey := string(consenter.GetClientTlsCert())
_, duplicateServerCert := seen[serverKey]
_, duplicateClientCert := seen[clientKey]
if duplicateServerCert || duplicateClientCert {
return errors.Errorf("duplicate consenter: server cert: %s, client cert: %s", serverKey, clientKey)
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure the config-update tooling marshals a valid ConfigMetadata with the full consenter list into consensusType.metadata
- Re-generate the channel config update with the correct protobuf field set (metadata containing consenters)
- If the error comes from your own caller, check md == nil before calling MetadataHasDuplication
Example fix
// before
if err := MetadataHasDuplication(md); err != nil { ... }
// after
if md == nil {
return errors.New("raft metadata missing from config update")
}
if err := MetadataHasDuplication(md); err != nil { ... } Defensive patterns
Strategy: validation
Validate before calling
// before invoking validation on config update
cv, _ := MetadataFromConfigValue(configValue)
if cv == nil {
return errors.New("config update carries no raft metadata")
}
if err := VerifyConfigMetadata(cv); err != nil {
return fmt.Errorf("invalid raft metadata: %w", err)
} Type guard
func hasRaftMetadata(md *etcdraft.ConfigMetadata) bool {
return md != nil
} Prevention
- Always populate consensusType.metadata when submitting etcdraft config updates
- Validate updates with configtxlator before submitting
- Check for nil metadata in tooling that switches consensus type
- Write integration tests that round-trip the config update protobuf
When it happens
Trigger: VerifyConfigMetadata (or MetadataFromConfigValue returning a nil metadata for a type change) hands a nil *etcdraft.ConfigMetadata into MetadataHasDuplication — e.g. a config update whose consensusType metadata field is empty.
Common situations: Channel update transaction built without the metadata field populated; a config tool marshaling an empty ConfigMetadata; switching consensus type where metadata is legitimately nil but validators are invoked unconditionally.
Related errors
- nil consenter in metadata
- failed to unmarshal consensusType config update
- failed to unmarshal updated (new) etcdraft metadata configur
- failed to extract envelope from the block
- nil Raft config metadata options
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/3db7bac6c685f88c.
Report an issue: GitHub.