hyperledger/fabric · error

failed signing Request

Error message

failed signing Request

What it means

Client.Send in discovery/client/client.go:169 signs the marshaled request payload with the configured Signer (c.signRequest). If signing fails (the signer returns an error), the failure is wrapped with 'failed signing Request'. Without a valid signature the discovery service would reject the request anyway.

Source

Thrown at discovery/client/client.go:169

}

func (req *Request) addQueryMapping(queryType protoext.QueryType, key string) {
	req.queryMapping[queryType][key] = req.lastIndex
	req.lastIndex++
}

// Send sends the request and returns the response, or error on failure
func (c *Client) Send(ctx context.Context, req *Request, auth *discovery.AuthInfo) (Response, error) {
	reqToBeSent := proto.Clone(req.Request).(*discovery.Request)
	reqToBeSent.Authentication = auth
	payload, err := proto.Marshal(reqToBeSent)
	if err != nil {
		return nil, errors.Wrap(err, "failed marshaling Request to bytes")
	}

	sig, err := c.signRequest(payload)
	if err != nil {
		return nil, errors.Wrap(err, "failed signing Request")
	}

	conn, err := c.createConnection()
	if err != nil {
		return nil, errors.Wrap(err, "failed connecting to discovery service")
	}

	cl := discovery.NewDiscoveryClient(conn)
	resp, err := cl.Discover(ctx, &discovery.SignedRequest{
		Payload:   payload,
		Signature: sig,
	})
	if err != nil {
		return nil, errors.Wrap(err, "discovery service refused our Request")
	}
	if n := len(resp.Results); n != req.lastIndex {
		return nil, errors.Errorf("Sent %d queries but received %d responses back", req.lastIndex, n)
	}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Verify the signer identity's private key exists and is readable (msp/keystore) and the certificate matches it
  2. If using an HSM, check PKCS#11 configuration, PIN, and that the HSM is reachable
  3. Ensure the Client was created with a valid, non-nil Signer via discovery.NewClient(..., signer, ...) that returns (sig, nil)
  4. Test the signer standalone: call signer([]byte("test")) and confirm it succeeds before invoking Send

Example fix

// before: signer that swallows key-load errors and returns nil, err
signer := func(msg []byte) ([]byte, error) { return key.Sign(msg) }

// after: fail fast with a validated signer
key, err := loadPrivateKey("msp/keystore/key.pem")
if err != nil { return fmt.Errorf("cannot load signing key: %w", err) }
signer := func(msg []byte) ([]byte, error) { return key.Sign(msg) }
Defensive patterns

Strategy: validation

Validate before calling

sig, err := signer([]byte("probe"))
if err != nil || len(sig) == 0 {
    return fmt.Errorf("signer unavailable: %w", err)
}

Type guard

func signerHealthy(s discovery.Signer) bool {
    sig, err := s([]byte("probe"))
    return err == nil && len(sig) > 0
}

Try / catch

resp, err := client.Send(ctx, req, auth)
if err != nil && strings.Contains(err.Error(), "failed signing Request") {
    return fmt.Errorf("check keystore/HSM and identity material: %w", err)
}

Prevention

When it happens

Trigger: Send is called with a Signer that errors — e.g. the signing identity's private key is missing, locked, or the signer function was not configured (nil/misbehaving signer, like in TestUnableToSign).

Common situations: MSP directory missing the keystore/private key; HSM unavailable or PIN wrong; signer configured with the wrong identity for the target channel's TLS/auth context.

Related errors


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