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

  1. Remove or rename the unexpected value key so it matches the known schema (e.g. "MSP", "Endpoints", "ConsensusType")
  2. Align Fabric versions — upgrade the parsing binary if the key is from a newer release
  3. 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

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


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/f1153062a880987b. Report an issue: GitHub.