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

  1. Regenerate the consensus metadata from the canonical configtx.yaml / configtxlator pipeline instead of hand-editing bytes.
  2. Decode the metadata with 'configtxlator proto_decode --type etcdraft.ConfigMetadata' to inspect the corruption.
  3. Ensure the tooling and Fabric versions used to produce the update match the running orderers.
  4. 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

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


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