hyperledger/fabric · error

error mapping ReadSet

Error message

error mapping ReadSet

What it means

mapConfig failed while converting the update's ReadSet into the internal comparable map. This wraps an underlying error such as a bad group path, an invalid item type, or keys in unexpected positions in the config tree. The ReadSet could not be processed, so authorization stops.

Source

Thrown at common/configtx/update.go:132

// authorizeUpdate validates that all modified config has the corresponding modification policies satisfied by the signature set
// it returns a map of the modified config
func (vi *ValidatorImpl) authorizeUpdate(configUpdateEnv *cb.ConfigUpdateEnvelope) (map[string]comparable, error) {
	if configUpdateEnv == nil {
		return nil, errors.Errorf("cannot process nil ConfigUpdateEnvelope")
	}

	configUpdate, err := UnmarshalConfigUpdate(configUpdateEnv.ConfigUpdate)
	if err != nil {
		return nil, err
	}

	if configUpdate.ChannelId != vi.channelID {
		return nil, errors.Errorf("ConfigUpdate for channel '%s' but envelope for channel '%s'", configUpdate.ChannelId, vi.channelID)
	}

	readSet, err := mapConfig(configUpdate.ReadSet, vi.namespace)
	if err != nil {
		return nil, errors.Wrapf(err, "error mapping ReadSet")
	}
	err = vi.verifyReadSet(readSet)
	if err != nil {
		return nil, errors.Wrapf(err, "error validating ReadSet")
	}

	writeSet, err := mapConfig(configUpdate.WriteSet, vi.namespace)
	if err != nil {
		return nil, errors.Wrapf(err, "error mapping WriteSet")
	}

	deltaSet := computeDeltaSet(readSet, writeSet)
	signedData, err := protoutil.ConfigUpdateEnvelopeAsSignedData(configUpdateEnv)
	if err != nil {
		return nil, err
	}

	if err = vi.verifyDeltaSet(deltaSet, signedData); err != nil {

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Inspect the wrapped inner error to locate the offending ReadSet entry/path.
  2. Rebuild the ReadSet via configtxlator from the actual current config (ReadSet entries must exist in the current config with matching versions).
  3. Do not hand-edit serialized update protos; regenerate the diff programmatically.
  4. Validate the update JSON/YAML schema before encoding to protobuf.

Example fix

// before: read_set group path "Application/OrgsMSP" (wrong segment)
// after: correct path mirroring config tree, e.g. "groups/Application/groups/Org1"
Defensive patterns

Strategy: validation

Validate before calling

// Sanity-check ReadSet structure before submission
func validReadSet(update *cb.ConfigUpdate) error {
    rs := update.GetReadSet()
    for g := range rs.GetGroups() {
        if g == "" { return errors.New("read_set has empty group key") }
    }
    for k := range rs.GetValues() {
        if k == "" { return errors.New("read_set has empty value key") }
    }
    return nil
}

Try / catch

if _, err := validator.ProposeConfigUpdate(env, seq); err != nil {
    if strings.Contains(err.Error(), "error mapping ReadSet") {
        // regenerate read_set from the live config via configtxlator
    }
    return err
}

Prevention

When it happens

Trigger: Calling proposeConfigUpdate/Validate with a ConfigUpdate whose ReadSet contains entries with invalid group paths, illegal key encodings, or items that mapConfig cannot classify (e.g. policies/values/groups in wrong positions).

Common situations: Manually edited protobuf update files; tooling producing nested group paths that don't mirror the config hierarchy; corrupted update transmitted over the wire.

Related errors


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