hyperledger/fabric · error

signature mismatch

Error message

signature mismatch

What it means

VerifyAuthRequest verifies that the incoming request payload was actually signed by the claimed sender. It computes SHA256Digest(msg) over the request bytes and calls VerifySignature with the sender's identity (fromIdentity) and authReq.Signature. If signature verification fails, the request may have been tampered with, the payload/signature got out of sync, or the signature was produced with a key that doesn't match fromIdentity.

Source

Thrown at orderer/common/cluster/clusterservice.go:177

	}

	toIdentity := membership.MemberMapping[authReq.ToId]
	if toIdentity == nil {
		return nil, errors.Errorf("node %d is not member of channel %s", authReq.ToId, authReq.Channel)
	}

	equal, err := CompareCertPublicKeys(toIdentity, s.NodeIdentity)
	if err != nil {
		return nil, errors.Wrap(err, "failed to compare cert public keys")
	}
	if !equal {
		s.Logger.Debugf("node id mismatch for node %d, toIdentity: %s, s.NodeIdentity: %s", authReq.FromId, string(toIdentity), string(s.NodeIdentity))
		return nil, errors.Errorf("node id mismatch")
	}

	err = VerifySignature(fromIdentity, SHA256Digest(msg), authReq.Signature)
	if err != nil {
		return nil, errors.Wrap(err, "signature mismatch")
	}

	return authReq, nil
}

func (s *ClusterService) handleMessage(stream ClusterStepStream, addr string, exp *certificateExpirationCheck, channel string, sender uint64, streamID uint64) error {
	request, err := stream.Recv()
	if err == io.EOF {
		return err
	}
	if err != nil {
		s.Logger.Warningf("Stream read from %s failed: %v", addr, err)
		return err
	}
	if request == nil {
		return errors.Errorf("request message is nil")
	}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Re-enroll/restart the sending node so its signing key matches the certificate distributed in the channel/MSP configuration.
  2. On the sender, confirm the request is signed over the exact serialized payload (SHA-256 digest) as received — regenerate the signature rather than reusing cached ones.
  3. Remove any intermediaries that modify bodies (disable LB/mesh body rewriting) between the two orderers.
  4. Ensure all Fabric orderer binaries are the same version so serialization and auth request formats agree.
  5. Compare the sender's certificate on disk with the one in the channel's MSP and update the MSP config if the cert was rotated.

Example fix

// before (sender caches signature from an older payload)
req.Signature = cachedSig
req.Payload = newPayload
// after — always sign the exact bytes sent
msg := payloadBytes
digest := sha256.Sum256(msg)
req.Payload = msg
req.Signature = signer.Sign(digest[:])
Defensive patterns

Strategy: validation

Validate before calling

// Sender-side pre-flight: sign exactly the bytes being sent
digest := sha256.Sum256(payload)
sig, err := signer.Sign(digest[:])
if err != nil { return err }
// verify locally before sending
if err := VerifySignature(localIdentity, digest[:], sig); err != nil {
    return fmt.Errorf("local signature would fail remote verification: %w", err)
}

Try / catch

err := stepClient.Send(signedRequest)
if err != nil && strings.Contains(err.Error(), "signature mismatch") {
    // re-sign with the current signer and retry once
    signedRequest.Signature = resign(signedRequest.Payload)
    err = stepClient.Send(signedRequest)
}

Prevention

When it happens

Trigger: ClusterService.Step receives a SignedRequest whose Signature field does not verify against the SHA-256 digest of its payload using the sender's enrolled client certificate — e.g. a client (or another orderer) signs with a different/stale key, the payload was modified after signing, or a proxy re-encoded the message bytes so the digest no longer matches.

Common situations: A replicated state issue where an orderer was re-enrolled (new key) but peers/services cache the old certificate; a manual or buggy client constructs Submit/Step requests without signing the exact serialized bytes; middleware (LB, service mesh) alters request bodies; Fabric binaries at mixed versions where request serialization differs.

Related errors


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