hyperledger/fabric · critical

invalid signer. cannot be nil

Error message

invalid signer. cannot be nil

What it means

NewSignatureHeaderOrPanic panics immediately with 'invalid signer. cannot be nil' when the identity.Serializer argument is nil. It is a fail-fast precondition: creating a SignatureHeader requires serializing a signing identity, so a nil signer is a programming error rather than a runtime condition.

Source

Thrown at protoutil/commonutils.go:168

	creator, err := id.Serialize()
	if err != nil {
		return nil, err
	}
	nonce, err := CreateNonce()
	if err != nil {
		return nil, err
	}

	return &cb.SignatureHeader{
		Creator: creator,
		Nonce:   nonce,
	}, nil
}

// NewSignatureHeaderOrPanic returns a signature header and panics on error.
func NewSignatureHeaderOrPanic(id identity.Serializer) *cb.SignatureHeader {
	if id == nil {
		panic(errors.New("invalid signer. cannot be nil"))
	}

	signatureHeader, err := NewSignatureHeader(id)
	if err != nil {
		panic(fmt.Errorf("failed generating a new SignatureHeader: %s", err))
	}

	return signatureHeader
}

// SignOrPanic signs a message and panics on error.
func SignOrPanic(signer identity.Signer, msg []byte) []byte {
	if signer == nil {
		panic(errors.New("invalid signer. cannot be nil"))
	}

	sigma, err := signer.Sign(msg)
	if err != nil {

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure a valid signing identity is loaded (local MSP / identity.Serializer) before constructing the block publisher or signer that reaches this call.
  2. Check the code path that injects the signer — fix nil wiring (e.g. a constructor receiving a nil signer dependency).
  3. Use the non-panicking NewSignatureHeader and validate id != nil yourself if nil signers are expected at runtime.
  4. If using fabric-sdk, confirm the client was created with credentials (wallet/identity) before signing operations.

Example fix

// before
sigHdr := protoutil.NewSignatureHeaderOrPanic(signer) // panics if signer==nil
// after
if signer == nil {
    return errors.New("signer not configured; check local MSP/identity setup")
}
sigHdr, err := protoutil.NewSignatureHeader(signer)
Defensive patterns

Strategy: validation

Validate before calling

if signer == nil {
    return errors.New("signing identity not configured; check local MSP setup")
}
sigHdr := protoutil.NewSignatureHeaderOrPanic(signer)

Type guard

func hasSerializer(id identity.Serializer) bool {
    return id != nil
}

Try / catch

func safeSigHeader(id identity.Serializer) (hdr *cb.SignatureHeader, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("NewSignatureHeaderOrPanic: %v", r)
        }
    }()
    hdr = protoutil.NewSignatureHeaderOrPanic(id)
    return
}

Prevention

When it happens

Trigger: Calling NewSignatureHeaderOrPanic(nil) — e.g. the signing identity was never loaded from MSP/certificate material, a dependency injection returned nil, or an <anonymous> callback passed through an unset signer variable.

Common situations: Orderer/peer code paths (addBlockSignature) where the signer dependency wasn't initialized because local MSP config is missing or empty; SDK apps constructing blocks without a loaded identity; late-binding of signer after config load failure.

Related errors


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