{"record":{"id":"f1153062a880987b","repo":"hyperledger/fabric","slug":"unexpected-key-s","errorCode":null,"errorMessage":"Unexpected key %s","messagePattern":"Unexpected key (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/channelconfig/standardvalues.go","lineNumber":62,"sourceCode":"\t}\n\n\tfor _, protosStruct := range protosStructs {\n\t\tlogger.Debugf(\"Initializing protos for %T\\n\", protosStruct)\n\t\tif err := sv.initializeProtosStruct(reflect.ValueOf(protosStruct)); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn sv, nil\n}\n\n// Deserialize looks up the backing Values proto of the given name, unmarshals the given bytes\n// to populate the backing message structure, and returns a referenced to the retained deserialized\n// message (or an error, either because the key did not exist, or there was an error unmarshalling\nfunc (sv *StandardValues) Deserialize(key string, value []byte) (proto.Message, error) {\n\tmsg, ok := sv.lookup[key]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"Unexpected key %s\", key)\n\t}\n\n\terr := proto.Unmarshal(value, msg)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn msg, nil\n}\n\nfunc (sv *StandardValues) initializeProtosStruct(objValue reflect.Value) error {\n\tobjType := objValue.Type()\n\tif objType.Kind() != reflect.Pointer {\n\t\treturn fmt.Errorf(\"Non pointer type\")\n\t}\n\tif objType.Elem().Kind() != reflect.Struct {\n\t\treturn fmt.Errorf(\"Non struct type\")\n\t}","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/channelconfig/standardvalues.go#L44-L80","documentation":"StandardValues.Deserialize looks up a config Value key in the fixed set of proto messages registered for that Values implementation. If the key is not in the lookup map, the group contains a value this config type does not understand, so it fails with \"Unexpected key\". It guards the strongly-typed proto mapping of channel config values.","triggerScenarios":"A ConfigGroup Value whose key does not correspond to any registered proto field for that group — e.g. adding a custom/typo'd value key to an org/orderer/application group, or a config written by a newer Fabric version introducing keys an older version's channelconfig package doesn't know.","commonSituations":"Typo in value keys when hand-assembling config updates; mixing Fabric versions (config from v2.x keys parsed by older code); plugins/custom tooling injecting extra values into standard groups.","solutions":["Remove or rename the unexpected value key so it matches the known schema (e.g. \"MSP\", \"Endpoints\", \"ConsensusType\")","Align Fabric versions — upgrade the parsing binary if the key is from a newer release","Put custom data in an appropriate extension group (Capabilities, custom orderer group) rather than unknown value keys"],"exampleFix":"// before\nvalues := map[string]*cb.ConfigValue{\"Msps\": {Value: mspBytes}}\n// after\nvalues := map[string]*cb.ConfigValue{\"MSP\": {Value: mspBytes}}","handlingStrategy":"validation","validationCode":"knownKeys := map[string]bool{\"MSP\": true, \"Endpoints\": true}\nfor k := range orgGroup.Values {\n\tif !knownKeys[k] {\n\t\treturn fmt.Errorf(\"unknown org value key %q\", k)\n\t}\n}","typeGuard":null,"tryCatchPattern":"msg, err := sv.Deserialize(key, value)\nif err != nil {\n\tif strings.HasPrefix(err.Error(), \"Unexpected key\") {\n\t\treturn fmt.Errorf(\"value key %q is not part of this config schema; check Fabric version and key spelling: %w\", key, err)\n\t}\n\treturn err\n}","preventionTips":["Only use documented value keys for each group type; extend via proper extension points, not ad-hoc keys","Keep Fabric binaries and config-generation tooling on the same version","Spell-check keys against the Fabric protos when hand-assembling updates"],"tags":["hyperledger-fabric","channelconfig","proto","schema"],"backgroundTag":"unexpected-config-key","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"}