hyperledger/fabric · error

No signatures for nil SignedConfigItem

Error message

No signatures for nil SignedConfigItem

What it means

ConfigUpdateEnvelopeAsSignedData converts the signatures of a common.ConfigUpdateEnvelope into SignedData entries for signature verification. The function cannot produce any signed data from a nil envelope, so it returns this error before touching ce.Signatures.

Source

Thrown at protoutil/signeddata.go:37

	"google.golang.org/protobuf/proto"
)

// SignedData is used to represent the general triplet required to verify a signature
// This is intended to be generic across crypto schemes, while most crypto schemes will
// include the signing identity and a nonce within the Data, this is left to the crypto
// implementation.
type SignedData struct {
	Data      []byte
	Identity  []byte
	Signature []byte
}

// ConfigUpdateEnvelopeAsSignedData returns the set of signatures for the
// ConfigUpdateEnvelope as SignedData or an error indicating why this was not
// possible.
func ConfigUpdateEnvelopeAsSignedData(ce *common.ConfigUpdateEnvelope) ([]*SignedData, error) {
	if ce == nil {
		return nil, errors.New("No signatures for nil SignedConfigItem")
	}

	result := make([]*SignedData, len(ce.Signatures))
	for i, configSig := range ce.Signatures {
		sigHeader := &common.SignatureHeader{}
		err := proto.Unmarshal(configSig.SignatureHeader, sigHeader)
		if err != nil {
			return nil, err
		}

		result[i] = &SignedData{
			Data:      bytes.Join([][]byte{configSig.SignatureHeader, ce.ConfigUpdate}, nil),
			Identity:  sigHeader.Creator,
			Signature: configSig.Signature,
		}

	}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Check the envelope for nil before calling, and skip or reject the config update when nil.
  2. Fix the upstream code path so a nil envelope short-circuits with its real error instead of being passed along.
  3. Unmarshal the ConfigUpdateEnvelope from the payload before invoking, and fail fast on unmarshal errors.
  4. In tests, construct a real envelope (even empty but non-nil) instead of passing nil.

Example fix

// before
sigs, err := protoutil.ConfigUpdateEnvelopeAsSignedData(env)

// after
if env == nil {
    return errors.New("no config update envelope")
}
sigs, err := protoutil.ConfigUpdateEnvelopeAsSignedData(env)
Defensive patterns

Strategy: type-guard

Validate before calling

if ce == nil {
    return nil, errors.New("config update envelope required for signature verification")
}
if len(ce.Signatures) == 0 {
    return nil, errors.New("config update has no signatures")
}

Type guard

func isNilEnvelope(v interface{}) bool { return v == nil }

Try / catch

sd, err := protoutil.ConfigUpdateEnvelopeAsSignedData(ce)
if err != nil {
    return fmt.Errorf("cannot authorize config update: %w", err)
}

Prevention

When it happens

Trigger: Calling ConfigUpdateEnvelopeAsSignedData with a nil *common.ConfigUpdateEnvelope — typically from authorizeUpdate when the config update envelope failed to be constructed or passed through as nil.

Common situations: Orderer config processing where an earlier unmarshal returned (nil, err) but the error was ignored; tests passing nil envelopes; code paths where the config transaction was rejected earlier but the envelope still flows into signature collection.

Related errors


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