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

  1. Ensure the config-update tooling marshals a valid ConfigMetadata with the full consenter list into consensusType.metadata
  2. Re-generate the channel config update with the correct protobuf field set (metadata containing consenters)
  3. 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

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


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