hyperledger/fabric · critical

could not sign the proposal response payload

Error message

could not sign the proposal response payload

What it means

The default endorsement plugin signs the concatenation of the proposal response payload (prpBytes) and the serialized endorser identity using the signer's private key. This error wraps a failure from signer.Sign(), meaning the underlying BCCSP crypto layer could not produce the ECDSA signature.

Source

Thrown at core/handlers/endorsement/builtin/default_endorsement.go:49

// Returns:
// The Endorsement: A signature over the payload, and an identity that is used to verify the signature
// The payload that was given as input (could be modified within this function)
// Or error on failure
func (e *DefaultEndorsement) Endorse(prpBytes []byte, sp *peer.SignedProposal) (*peer.Endorsement, []byte, error) {
	signer, err := e.SigningIdentityForRequest(sp)
	if err != nil {
		return nil, nil, errors.Wrap(err, "failed fetching signing identity")
	}
	// serialize the signing identity
	identityBytes, err := signer.Serialize()
	if err != nil {
		return nil, nil, errors.Wrapf(err, "could not serialize the signing identity")
	}

	// sign the concatenation of the proposal response and the serialized endorser identity with this endorser's key
	signature, err := signer.Sign(append(prpBytes, identityBytes...))
	if err != nil {
		return nil, nil, errors.Wrapf(err, "could not sign the proposal response payload")
	}
	endorsement := &peer.Endorsement{Signature: signature, Endorser: identityBytes}
	return endorsement, prpBytes, nil
}

// Init injects dependencies into the instance of the Plugin
func (e *DefaultEndorsement) Init(dependencies ...endorsement.Dependency) error {
	for _, dep := range dependencies {
		sIDFetcher, isSigningIdentityFetcher := dep.(identities.SigningIdentityFetcher)
		if !isSigningIdentityFetcher {
			continue
		}
		e.SigningIdentityFetcher = sIDFetcher
		return nil
	}
	return errors.New("could not find SigningIdentityFetcher in dependencies")
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Check the wrapped error in the peer log to confirm whether the keystore or HSM is the cause
  2. Ensure peer.mspConfigPath keystore contains the private key matching signcerts, with correct file permissions for the peer user
  3. Validate BCCSP PKCS#11 settings (library, label, pin, slot) against the actual HSM configuration
  4. Restart the peer after restoring or regenerating crypto material

Example fix

// before: keystore missing after volume remount
//   could not sign the proposal response payload: ... no such file: keystore/*_sk
// after: restore key material matching the signing cert
// ls /var/hyperledger/msp/keystore  # must contain *_sk for the cert in signcerts
// chown -R peer:peer /var/hyperledger/msp && docker restart peer0.org1.example.com
Defensive patterns

Strategy: validation

Validate before calling

// confirm key material exists and is readable before endorsing
matches, _ := filepath.Glob(filepath.Join(mspPath, "keystore", "*_sk"))
if len(matches) == 0 { return errors.New("no private key in keystore") }

Try / catch

sig, err := signer.Sign(payload)
if err != nil {
    logger.Errorf("endorsement signing failed (check keystore/HSM): %v", err)
    return nil, status.Error(codes.Internal, "endorsement signing unavailable")
}

Prevention

When it happens

Trigger: DefaultEndorsement.Endorse calls signer.Sign(append(prpBytes, identityBytes...)) and the signing operation fails — e.g. the private key cannot be accessed, the keystore is unreadable, or an HSM/PKCS#11 operation returns an error.

Common situations: Peer's keystore file deleted or permissions changed after start; PKCS#11 HSM session/token failure or wrong slot/pin configured in BCCSP; key migrated between software and HSM so the referenced private key no longer exists.

Related errors


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