{"record":{"id":"6208458f0c7e8c98","repo":"hyperledger/fabric","slug":"failed-to-deserialize-values-620845","errorCode":null,"errorMessage":"failed to deserialize values","messagePattern":"failed to deserialize values","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/channelconfig/channel.go","lineNumber":90,"sourceCode":"\tprotos *ChannelProtos\n\n\thashingAlgorithm func(input []byte) []byte\n\n\tmspManager msp.MSPManager\n\n\tappConfig         *ApplicationConfig\n\tordererConfig     *OrdererConfig\n\tconsortiumsConfig *ConsortiumsConfig\n}\n\n// NewChannelConfig creates a new ChannelConfig\nfunc NewChannelConfig(channelGroup *cb.ConfigGroup, bccsp bccsp.BCCSP) (*ChannelConfig, error) {\n\tcc := &ChannelConfig{\n\t\tprotos: &ChannelProtos{},\n\t}\n\n\tif err := DeserializeProtoValuesFromGroup(channelGroup, cc.protos); err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to deserialize values\")\n\t}\n\n\tchannelCapabilities := cc.Capabilities()\n\n\tif err := cc.Validate(channelCapabilities); err != nil {\n\t\treturn nil, err\n\t}\n\n\tmspConfigHandler := NewMSPConfigHandler(channelCapabilities.MSPVersion(), bccsp)\n\n\tvar err error\n\tfor groupName, group := range channelGroup.Groups {\n\t\tswitch groupName {\n\t\tcase ApplicationGroupKey:\n\t\t\tcc.appConfig, err = NewApplicationConfig(group, mspConfigHandler)\n\t\tcase OrdererGroupKey:\n\t\t\tcc.ordererConfig, err = NewOrdererConfig(group, mspConfigHandler, channelCapabilities)\n\t\tcase ConsortiumsGroupKey:","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/channelconfig/channel.go#L72-L108","documentation":"NewChannelConfig deserializes each config value in the channel group into typed protobuf structs via DeserializeProtoValuesFromGroup; if any value fails to unmarshal, the error is wrapped as \"failed to deserialize values\". It indicates a value in the Channel group (e.g. HashingAlgorithm, BlockDataHashingStructure, OrdererAddresses, Capabilities) is malformed or of the wrong type.","triggerScenarios":"Calling NewChannelConfig (directly, via NewBundle, or via extractChannelConfig) with a channelGroup whose Values contain a Value byte slice that does not unmarshal as the expected message type — e.g. a Capabilities value stored where OrdererAddresses is expected, or a hand-edited/truncated proto payload.","commonSituations":"Manually editing config after configtxlator decode/encode round-trips; corruption from re-encoding with mismatched field types; copy-pasting value blobs between config keys; building cb.ConfigValue in tests with wrong payload types.","solutions":["Round-trip the config through `configtxlator proto_decode` and inspect each value under groups.Channel.values for mismatched/corrupt payloads","Regenerate the channel config with configtxgen from the original configtx.yaml instead of editing blobs","In code, verify each cb.ConfigValue marshals the exact proto type expected for its key (e.g. cb.Capabilities for CapabilitiesKey)","Log the underlying wrapped error to identify which specific value failed"],"exampleFix":"// before\nvalues[\"OrdererAddresses\"] = &cb.ConfigValue{Value: protoutil.MarshalOrPanic(&cb.Capabilities{...})} // wrong type\n\n// after\nvalues[\"OrdererAddresses\"] = &cb.ConfigValue{\n    Value: protoutil.MarshalOrPanic(&cb.OrdererAddresses{Addresses: []string{\"orderer.example.com:7050\"}}),\n}","handlingStrategy":"validation","validationCode":"for name, val := range channelGroup.Values {\n    if val == nil || len(val.Value) == 0 {\n        return fmt.Errorf(\"channel value %q has empty payload\", name)\n    }\n}\n// prefer round-tripping through configtxlator to catch type mismatches before NewBundle","typeGuard":null,"tryCatchPattern":"cc, err := channelconfig.NewChannelConfig(channelGroup, bccsp)\nif err != nil {\n    var cause string\n    if strings.Contains(err.Error(), \"failed to deserialize values\") {\n        cause = \"a channel-group value is corrupt or wrong type; regenerate with configtxgen\"\n    }\n    return fmt.Errorf(\"%s: %w\", cause, err)\n}","preventionTips":["Never hand-edit marshaled proto blobs; always decode/encode via configtxlator","Marshal the exact proto type for each well-known config key","Keep the raw proto unmarshal error when logging to identify the failing value"],"tags":["fabric","channelconfig","protobuf","deserialization"],"backgroundTag":"protobuf-deserialization-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"}