hyperledger/fabric · error
Unexpected key %s
Error message
Unexpected key %s
What it means
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.
Source
Thrown at common/channelconfig/standardvalues.go:62
}
for _, protosStruct := range protosStructs {
logger.Debugf("Initializing protos for %T\n", protosStruct)
if err := sv.initializeProtosStruct(reflect.ValueOf(protosStruct)); err != nil {
return nil, err
}
}
return sv, nil
}
// Deserialize looks up the backing Values proto of the given name, unmarshals the given bytes
// to populate the backing message structure, and returns a referenced to the retained deserialized
// message (or an error, either because the key did not exist, or there was an error unmarshalling
func (sv *StandardValues) Deserialize(key string, value []byte) (proto.Message, error) {
msg, ok := sv.lookup[key]
if !ok {
return nil, fmt.Errorf("Unexpected key %s", key)
}
err := proto.Unmarshal(value, msg)
if err != nil {
return nil, err
}
return msg, nil
}
func (sv *StandardValues) initializeProtosStruct(objValue reflect.Value) error {
objType := objValue.Type()
if objType.Kind() != reflect.Pointer {
return fmt.Errorf("Non pointer type")
}
if objType.Elem().Kind() != reflect.Struct {
return fmt.Errorf("Non struct type")
}View on GitHub (pinned to 2736b63f8f)
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
Example fix
// before
values := map[string]*cb.ConfigValue{"Msps": {Value: mspBytes}}
// after
values := map[string]*cb.ConfigValue{"MSP": {Value: mspBytes}} Defensive patterns
Strategy: validation
Validate before calling
knownKeys := map[string]bool{"MSP": true, "Endpoints": true}
for k := range orgGroup.Values {
if !knownKeys[k] {
return fmt.Errorf("unknown org value key %q", k)
}
} Try / catch
msg, err := sv.Deserialize(key, value)
if err != nil {
if strings.HasPrefix(err.Error(), "Unexpected key") {
return fmt.Errorf("value key %q is not part of this config schema; check Fabric version and key spelling: %w", key, err)
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- failed to deserialize values
- Disallowed channel group: %s
- some orderer organizations endpoints are empty: %s
- organizations do not support sub-groups
- MSP for org %s has empty MSP ID
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/f1153062a880987b.
Report an issue: GitHub.