hyperledger/fabric · error
failed to unmarshal new etcdraft metadata configuration
Error message
failed to unmarshal new etcdraft metadata configuration
What it means
Returned when the new channel config's consensus metadata cannot be unmarshaled into an etcdraft.ConfigMetadata protobuf. Unlike the old-metadata failure (which panics as a programming error), a bad NEW config is treated as a user configuration error and wrapped with this message.
Source
Thrown at orderer/consensus/etcdraft/chain.go:1502
if oldOrdererConfig == nil {
c.logger.Panic("Programming Error: ValidateConsensusMetadata called with nil old channel config")
return nil
}
if oldOrdererConfig.ConsensusMetadata() == nil {
c.logger.Panic("Programming Error: ValidateConsensusMetadata called with nil old metadata")
return nil
}
oldMetadata := &etcdraft.ConfigMetadata{}
if err := proto.Unmarshal(oldOrdererConfig.ConsensusMetadata(), oldMetadata); err != nil {
c.logger.Panicf("Programming Error: Failed to unmarshal old etcdraft consensus metadata: %v", err)
}
newMetadata := &etcdraft.ConfigMetadata{}
if err := proto.Unmarshal(newOrdererConfig.ConsensusMetadata(), newMetadata); err != nil {
return errors.Wrap(err, "failed to unmarshal new etcdraft metadata configuration")
}
verifyOpts, err := createX509VerifyOptions(newOrdererConfig)
if err != nil {
return errors.Wrapf(err, "failed to create x509 verify options from old and new orderer config")
}
if err := VerifyConfigMetadata(newMetadata, verifyOpts); err != nil {
return errors.Wrap(err, "invalid new config metadata")
}
if newChannel {
// check if the consenters are a subset of the existing consenters (system channel consenters)
set := ConsentersToMap(oldMetadata.GetConsenters())
for _, c := range newMetadata.GetConsenters() {
if !set.Exists(c) {
return errors.New("new channel has consenter that is not part of system consenter set")
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Regenerate the consensus metadata from the canonical configtx.yaml / configtxlator pipeline instead of hand-editing bytes.
- Decode the metadata with 'configtxlator proto_decode --type etcdraft.ConfigMetadata' to inspect the corruption.
- Ensure the tooling and Fabric versions used to produce the update match the running orderers.
- Rebuild the config update, re-sign, and resubmit.
Defensive patterns
Strategy: validation
Validate before calling
md := &etcdraft.ConfigMetadata{}
if err := proto.Unmarshal(newCfg.ConsensusMetadata, md); err != nil {
return fmt.Errorf("invalid etcdraft ConfigMetadata: %w", err)
}
if len(md.Consenters) == 0 { return errors.New("no consenters in metadata") } Try / catch
if strings.Contains(err.Error(), "failed to unmarshal new etcdraft metadata configuration") {
return regenerateConsensusMetadataViaConfigtxlator()
} Prevention
- Generate consensus metadata with configtxlator only.
- Match Fabric tooling versions with running orderers.
- Decode-and-inspect metadata before each config update.
- Never edit consensus metadata bytes manually.
When it happens
Trigger: A config update's ConsensusMetadata field contains bytes that are not a valid etcdraft ConfigMetadata — hand-edited or wrongly generated consensus metadata during raft membership changes or consensus-type migration.
Common situations: Manually editing consensus metadata in the channel config; using configtxlator output from a different Fabric version; corrupted update envelope; consenters/metadata built by incompatible tooling.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
Related errors
- failed to unmarshal ClusterMetadata: %s
- bad config message: %s
- failed to deserialize values
- illegal orderer config update detected: endpoints of org %s
- orderer org %s attempted to change MSP ID from %s to %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/89a524fcab0cec79.
Report an issue: GitHub.