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
- Regenerate the organization's MSP definition with configtxgen so mspConfig.Config contains a valid FabricMSPConfig.
- Verify MSPConfig.Type actually matches the payload type (FABRIC type must carry FabricMSPConfig bytes).
- Round-trip the config through configtxlator to confirm the inner FabricMSPConfig decodes.
- 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
- Ensure MSPConfig.Type matches the embedded payload type (FABRIC type must carry FabricMSPConfig bytes).
- Validate MSP definitions with configtxgen output before committing them to channel config.
- Test org MSP definitions by decoding with configtxlator before channel creation.
- Keep Fabric versions aligned between config producers and the discovery service.
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
- failed unmarshalling fabric msp config
- failed unmarshaling identity %s
- marshalling failed
- failed unmarshalling peer's identity
- failed parsing MSPConfig
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/0ed5c8207c4a826d.
Report an issue: GitHub.