{"record":{"id":"24602597f6165a02","repo":"hyperledger/fabric","slug":"failed-parsing-mspconfig","errorCode":null,"errorMessage":"failed parsing MSPConfig","messagePattern":"failed parsing MSPConfig","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"discovery/support/config/support.go","lineNumber":148,"sourceCode":"\t\t\t\tcontinue\n\t\t\t}\n\t\t\tres[mspID].Endpoint = append(res[mspID].Endpoint, &discovery.Endpoint{\n\t\t\t\tHost: host,\n\t\t\t\tPort: uint32(port),\n\t\t\t})\n\t\t}\n\t}\n\n\treturn res\n}\n\nfunc perOrgEndpointsByMSPID(ordererGrp map[string]*common.ConfigGroup) (map[string][]string, error) {\n\tres := make(map[string][]string)\n\n\tfor name, group := range ordererGrp {\n\t\tmspConfig := &msp.MSPConfig{}\n\t\tif err := proto.Unmarshal(group.Values[channelconfig.MSPKey].Value, mspConfig); err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"failed parsing MSPConfig\")\n\t\t}\n\t\t// Skip non fabric MSPs, as they don't carry useful information for service discovery.\n\t\t// An idemix MSP shouldn't appear inside an orderer group, but this isn't a fatal error\n\t\t// for the discovery service and we can just ignore it.\n\t\tif mspConfig.Type != int32(mspconstants.FABRIC) {\n\t\t\tlogger.Error(\"Orderer group\", name, \"is not a FABRIC MSP, but is of type\", mspConfig.Type)\n\t\t\tcontinue\n\t\t}\n\n\t\tfabricConfig := &msp.FabricMSPConfig{}\n\t\tif err := proto.Unmarshal(mspConfig.Config, fabricConfig); err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"failed marshaling FabricMSPConfig\")\n\t\t}\n\n\t\t// Initialize an empty MSP to address mapping.\n\t\tres[fabricConfig.Name] = nil\n\n\t\t// If the key has a corresponding value, it should unmarshal successfully.","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/discovery/support/config/support.go#L130-L166","documentation":"This error means the service discovery support could not proto-unmarshal the MSPConfig protobuf stored under the 'MSP' key of an orderer organization's config group while building the MSP-ID-to-endpoints map. It is thrown because a corrupt, empty, or non-protobuf value in the orderer group's MSP config makes it impossible to extract organization info needed for orderer endpoint discovery. The underlying protobuf error is wrapped with 'failed parsing MSPConfig'.","triggerScenarios":"perOrgEndpointsByMSPID iterates the channel config's orderer groups (via computeOrdererEndpoints) and calls proto.Unmarshal(group.Values[channelconfig.MSPKey].Value, &msp.MSPConfig{}); the error occurs when that value is empty/nil bytes, truncated, or not a valid serialized msp.MSPConfig protobuf.","commonSituations":"Hand-edited or tool-mangled genesis/channel config tx; config group fetched from a channel where the MSP value was corrupted in transit or storage; using a config block produced by a different/older proto schema version; passing a fabricated common.ConfigGroup in tests without populating Values[channelconfig.MSPKey].","solutions":["Validate the channel configuration block/protobuf bytes are intact (regenerate the genesis block or re-fetch the latest config block from orderers).","Ensure each orderer org group has a valid MSP value under channelconfig.MSPKey generated with configtxgen/configtxlator, not hand-written bytes.","Decode the config with configtxlator to confirm the MSPConfig is parseable before feeding it to discovery.","Check proto/schema version consistency between the component building the config and the discovery service."],"exampleFix":"// before (test/config fixture missing MSP value)\ngrp := &common.ConfigGroup{Values: map[string]*common.ConfigValue{}}\n// after\nmspCfg, _ := proto.Marshal(&msp.MSPConfig{Type: int32(mspconstants.FABRIC), Config: fabricCfgBytes})\ngrp := &common.ConfigGroup{Values: map[string]*common.ConfigValue{\n  channelconfig.MSPKey: {Value: mspCfg},\n}}","handlingStrategy":"validation","validationCode":"mspCfg := &msp.MSPConfig{}\nif group == nil || group.Values[channelconfig.MSPKey] == nil || len(group.Values[channelconfig.MSPKey].Value) == 0 {\n    return fmt.Errorf(\"org group %q has no MSP value\", name)\n}\nif err := proto.Unmarshal(group.Values[channelconfig.MSPKey].Value, mspCfg); err != nil {\n    return fmt.Errorf(\"org group %q has invalid MSPConfig: %w\", name, err)\n}","typeGuard":"func hasValidMSPValue(g *common.ConfigGroup) bool {\n    v := g.Values[channelconfig.MSPKey]\n    if v == nil || len(v.Value) == 0 {\n        return false\n    }\n    return proto.Unmarshal(v.Value, &msp.MSPConfig{}) == nil\n}","tryCatchPattern":"if err != nil {\n    var umErr *proto.UnmarshalError\n    if errors.As(err, &umErr) {\n        // skip or quarantine this org group instead of failing discovery\n    }\n    return nil, err\n}","preventionTips":["Always generate MSP config values with configtxgen/configtxlator, never hand-craft protobuf bytes.","Verify channel config blocks decode with `configtxlator proto_decode` before use.","Round-trip test fixtures through proto.Marshal before injecting them.","Keep proto library versions consistent across services producing and consuming config."],"tags":["protobuf","hyperledger-fabric","config","discovery"],"backgroundTag":"protobuf-unmarshal-failed","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}