hyperledger/fabric · error
claimed TLS cert hash is %v but actual TLS cert hash is %v
Error message
claimed TLS cert hash is %v but actual TLS cert hash is %v
What it means
The claimed TLS cert hash in the message does not match the hash of the actual TLS certificate on the gRPC connection. This is the core anti-replay binding check: it proves the signed message came over this specific TLS channel.
Source
Thrown at common/deliver/binding.go:59
}
}
// mutualTLSBinding enforces the client to send its TLS cert hash in the message,
// and then compares it to the computed hash that is derived
// from the gRPC context.
// In case they don't match, or the cert hash is missing from the request or
// there is no TLS certificate to be excavated from the gRPC context,
// an error is returned.
func mutualTLSBinding(ctx context.Context, claimedTLScertHash []byte) error {
if len(claimedTLScertHash) == 0 {
return errors.Errorf("client didn't include its TLS cert hash")
}
actualTLScertHash := util.ExtractCertificateHashFromContext(ctx)
if len(actualTLScertHash) == 0 {
return errors.Errorf("client didn't send a TLS certificate")
}
if !bytes.Equal(actualTLScertHash, claimedTLScertHash) {
return errors.Errorf("claimed TLS cert hash is %v but actual TLS cert hash is %v", claimedTLScertHash, actualTLScertHash)
}
return nil
}
// noopBinding is a BindingInspector that always returns nil
func noopBinding(_ context.Context, _ []byte) error {
return nil
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Recompute the TLS cert hash from the certificate actually presented on the current connection and resend
- Restart/reconnect the client after certificate rotation so the hash matches the new cert
- Verify the client hashes the same cert file configured for the TLS handshake
Defensive patterns
Strategy: validation
Validate before calling
actualHash := util.ExtractCertificateHashFromContext(ctx)
if !bytes.Equal(actualHash, claimedTLScertHash) {
return errors.New("stale TLS cert hash: reconnect and recompute")
} Try / catch
if err := inspector(ctx, msg); err != nil {
if strings.Contains(err.Error(), "claimed TLS cert hash is") {
return reconnectAndResend() // hash mismatch: rebind to current TLS channel
}
return err
} Prevention
- Recompute the cert hash after any certificate rotation
- Hash exactly the cert configured in the TLS handshake, not another file on disk
- Avoid reusing sessions across identity/certificate switches
When it happens
Trigger: A client sends a cert hash computed from one certificate while connecting with another (stale cached hash, cert rotated mid-session, or a forged/misrouted request).
Common situations: Certificate rotation without refreshing the client-side cached hash; multiple TLS certs on disk and the client hashes the wrong one; connection reused across identity switches.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- client didn't include its TLS cert hash
- client didn't send a TLS certificate
- no TLS certificate sent
- message is nil
- chaincode tls key not provided
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/44da542d57189ca7.
Report an issue: GitHub.