hyperledger/fabric · error

failed marshaling FabricMSPConfig

Error message

failed marshaling FabricMSPConfig

What it means

Despite the wording 'failed marshaling', this error is raised when proto.Unmarshal fails to decode the inner msp.FabricMSPConfig carried inside a FABRIC-type MSPConfig of an orderer org group. The discovery support needs the FabricMSPConfig (notably its Name) to key the endpoints map, so a corrupt inner payload is fatal here. The underlying decode error is wrapped with 'failed marshaling FabricMSPConfig'.

Source

Thrown at discovery/support/config/support.go:160

func perOrgEndpointsByMSPID(ordererGrp map[string]*common.ConfigGroup) (map[string][]string, error) {
	res := make(map[string][]string)

	for name, group := range ordererGrp {
		mspConfig := &msp.MSPConfig{}
		if err := proto.Unmarshal(group.Values[channelconfig.MSPKey].Value, mspConfig); err != nil {
			return nil, errors.Wrap(err, "failed parsing MSPConfig")
		}
		// Skip non fabric MSPs, as they don't carry useful information for service discovery.
		// An idemix MSP shouldn't appear inside an orderer group, but this isn't a fatal error
		// for the discovery service and we can just ignore it.
		if mspConfig.Type != int32(mspconstants.FABRIC) {
			logger.Error("Orderer group", name, "is not a FABRIC MSP, but is of type", mspConfig.Type)
			continue
		}

		fabricConfig := &msp.FabricMSPConfig{}
		if err := proto.Unmarshal(mspConfig.Config, fabricConfig); err != nil {
			return nil, errors.Wrap(err, "failed marshaling FabricMSPConfig")
		}

		// Initialize an empty MSP to address mapping.
		res[fabricConfig.Name] = nil

		// If the key has a corresponding value, it should unmarshal successfully.
		if perOrgAddresses := group.Values[channelconfig.EndpointsKey]; perOrgAddresses != nil {
			ordererEndpoints := &common.OrdererAddresses{}
			if err := proto.Unmarshal(perOrgAddresses.Value, ordererEndpoints); err != nil {
				return nil, errors.Wrap(err, "failed unmarshalling orderer addresses")
			}
			// Override the mapping because this orderer org config contains org-specific endpoints.
			res[fabricConfig.Name] = ordererEndpoints.Addresses
		}
	}

	return res, nil
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Regenerate the organization's MSP definition with configtxgen so mspConfig.Config contains a valid FabricMSPConfig.
  2. Verify MSPConfig.Type actually matches the payload type (FABRIC type must carry FabricMSPConfig bytes).
  3. Round-trip the config through configtxlator to confirm the inner FabricMSPConfig decodes.
  4. Align Fabric versions across components producing and consuming the channel config.

Example fix

// before: type set but payload is raw YAML/other bytes
mspCfg := &msp.MSPConfig{Type: int32(mspconstants.FABRIC), Config: yamlBytes}
// after
fabricCfg, _ := proto.Marshal(&msp.FabricMSPConfig{Name: "OrdererMSP", RootCerts: ...})
mspCfg := &msp.MSPConfig{Type: int32(mspconstants.FABRIC), Config: fabricCfg}
Defensive patterns

Strategy: validation

Validate before calling

if mspConfig.Type == int32(mspconstants.FABRIC) && len(mspConfig.Config) == 0 {
    return fmt.Errorf("FABRIC MSPConfig has empty embedded config")
}
fabricCfg := &msp.FabricMSPConfig{}
if err := proto.Unmarshal(mspConfig.Config, fabricCfg); err != nil {
    return fmt.Errorf("embedded FabricMSPConfig invalid: %w", err)
}

Type guard

func isDecodableFabricMSPConfig(c *msp.MSPConfig) bool {
    if c.Type != int32(mspconstants.FABRIC) || len(c.Config) == 0 {
        return false
    }
    return proto.Unmarshal(c.Config, &msp.FabricMSPConfig{}) == nil
}

Try / catch

if err := proto.Unmarshal(mspConfig.Config, fabricConfig); err != nil {
    return fmt.Errorf("failed marshaling FabricMSPConfig: %w", err)
}

Prevention

When it happens

Trigger: In perOrgEndpointsByMSPID, after mspConfig.Type == FABRIC passes, proto.Unmarshal(mspConfig.Config, &msp.FabricMSPConfig{}) fails because mspConfig.Config is empty, truncated, or was produced from a different message type (e.g. an idemix or other MSP's bytes mislabeled as FABRIC type).

Common situations: MSP config generated by mismatched Fabric versions where the embedded config bytes differ; someone set Type=FABRIC but put non-FabricMSPConfig bytes in Config; corrupted config block; test fixtures that fill Type but not Config.

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/0ed5c8207c4a826d. Report an issue: GitHub.