hyperledger/fabric · error

invalid new config metadata

Error message

invalid new config metadata

What it means

This wrapper error is returned when VerifyConfigMetadata rejects the new etcdraft config metadata during a config update (orderer/consensus/etcdraft/chain.go:1511). The metadata is verified against the x509 verify options built from the orderer config, meaning every consenter's server/client TLS and intermediate certs must validate. It wraps the specific reason the metadata failed verification.

Solutions

  1. Read the wrapped cause to identify which cert failed verification
  2. Ensure every consenter TLS cert chains to a CA listed in Orderer.TLS.RootCAs
  3. Replace expired certificates and resubmit the config update
  4. Verify metadata structure (cert fields present, base64-PEM correct) with configtxlator

Example fix

// before
consenters: [{host: node1, port: 7050, client_tls_cert: certA, server_tls_cert: certB}] // certB signed by unknown CA
// after
consenters: [{host: node1, port: 7050, client_tls_cert: certA, server_tls_cert: certA}] // both issued by root CA in Orderer.TLS.RootCAs
Defensive patterns

Strategy: validation

Validate before calling

if err := VerifyConfigMetadata(newMetadata, verifyOpts); err != nil {
    return fmt.Errorf("metadata rejected, fix certs against RootCAs: %w", err)
}

Type guard

func consenterCertsKnown(m *etcdraft.ConfigMetadata, rootCAs []*x509.Certificate) bool {
    for _, c := range m.GetConsenters() {
        if len(c.GetServerTlsCert()) == 0 || len(c.GetClientTlsCert()) == 0 { return false }
    }
    return len(rootCAs) > 0
}

Try / catch

if err := submitConfigUpdate(cfg); err != nil {
    if strings.Contains(err.Error(), "invalid new config metadata") {
        // inspect wrapped cause: which cert/field failed verification
    }
}

Prevention

When it happens

Trigger: A channel config update sets etcdraft consensus metadata whose consenters' TLS certificates do not verify against the orderer config's root CAs, or whose certificate/CA chains fail signature or expiration checks.

Common situations: Adding a new orderer consenter whose TLS cert was signed by a CA not in Orderer.TLS.RootCAs; expired consenter certificates; mismatched client/server cert pairs; editing metadata JSON by hand and breaking cert fields.

Related errors


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

Appendix: source

Thrown at orderer/consensus/etcdraft/chain.go:1511

	}

	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")
			}
		}
		return nil
	}

	// create the dummy parameters for ComputeMembershipChanges
	c.raftMetadataLock.RLock()
	dummyOldBlockMetadata := proto.Clone(c.opts.BlockMetadata).(*etcdraft.BlockMetadata)
	c.raftMetadataLock.RUnlock()

View on GitHub (pinned to 2736b63f8f)