hyperledger/fabric · error

cannot process nil ConfigUpdateEnvelope

Error message

cannot process nil ConfigUpdateEnvelope

What it means

authorizeUpdate was invoked with a nil ConfigUpdateEnvelope. The validator cannot authorize a config update without the envelope that carries the serialized ConfigUpdate and its signatures, so it fails immediately.

Source

Thrown at common/configtx/update.go:118

		}
	}
	return nil
}

func verifyFullProposedConfig(writeSet, fullProposedConfig map[string]comparable) error {
	for key := range writeSet {
		if _, ok := fullProposedConfig[key]; !ok {
			return errors.Errorf("writeset contained key %s which did not appear in proposed config", key)
		}
	}
	return nil
}

// 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")

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure a valid ConfigUpdateEnvelope is constructed (marshaled ConfigUpdate bytes plus signatures) before calling proposeConfigUpdate/Validate.
  2. Check the caller that produced the envelope for early unmarshal failures that left it nil.
  3. Guard the call site with a nil check and reject the transaction/proposal before invoking the validator.

Example fix

// before
newConfig, err := validator.proposeConfigUpdate(nil)
// after
if configEnv == nil {
    return errors.New("no config update envelope provided")
}
newConfig, err := validator.proposeConfigUpdate(configEnv)
Defensive patterns

Strategy: type-guard

Validate before calling

// Reject nil envelopes at the boundary before invoking the validator
func validateEnvelope(env *cb.ConfigUpdateEnvelope) error {
    if env == nil || len(env.GetConfigUpdate()) == 0 {
        return errors.New("empty ConfigUpdateEnvelope")
    }
    return nil
}

Type guard

func isNilEnvelope(env *cb.ConfigUpdateEnvelope) bool {
    return env == nil || env.GetConfigUpdate() == nil
}

Try / catch

if isNilEnvelope(env) {
    return errors.New("config update envelope is nil")
}
if _, err := validator.ProposeConfigUpdate(env, seq); err != nil {
    return err
}

Prevention

When it happens

Trigger: Calling proposeConfigUpdate or Validate and passing a nil envelope — e.g. when the enclosing envelope's payload failed to unmarshal earlier, or the caller passes nil directly.

Common situations: Submitting an empty/garbage transaction to the orderer that unmarshals to a nil envelope; a bug in calling code that skips envelope construction; transaction filtered to nil upstream then still validated.

Related errors


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