hyperledger/fabric · warning
public keys do not match
Error message
public keys do not match
What it means
ErrPubKeyMismatch is returned by CertificatesWithSamePublicKey when two certificates compared for key-equivalence do not share the same public key. It's a sentinel error used to distinguish a benign mismatch from actual comparison failures.
Source
Thrown at common/crypto/expiration.go:104
info("The %s certificate will expire on %s", certRole, expirationTime)
if timeLeftUntilExpiration < oneWeek {
days := timeLeftUntilExpiration / (time.Hour * 24)
hours := (timeLeftUntilExpiration - (days * time.Hour * 24)) / time.Hour
warn("The %s certificate expires within %d days and %d hours", certRole, days, hours)
return
}
timeLeftUntilOneWeekBeforeExpiration := timeLeftUntilExpiration - oneWeek
sched(timeLeftUntilOneWeekBeforeExpiration, func() {
warn("The %s certificate will expire within one week", certRole)
})
}
// ErrPubKeyMismatch is used by CertificatesWithSamePublicKey to indicate the two public keys mismatch
var ErrPubKeyMismatch = errors.New("public keys do not match")
// LogNonPubKeyMismatchErr logs an error which is not an ErrPubKeyMismatch error
func LogNonPubKeyMismatchErr(log func(template string, args ...any), err error, cert1DER, cert2DER []byte) {
cert1PEM := &pem.Block{Type: "CERTIFICATE", Bytes: cert1DER}
cert2PEM := &pem.Block{Type: "CERTIFICATE", Bytes: cert2DER}
log("Failed determining if public key of %s matches public key of %s: %s",
string(pem.EncodeToMemory(cert1PEM)),
string(pem.EncodeToMemory(cert2PEM)),
err)
}
// CertificatesWithSamePublicKey returns nil if both byte slices
// are valid DER encoding of certificates with the same public key.
func CertificatesWithSamePublicKey(der1, der2 []byte) error {
cert1canonized, err := publicKeyFromCertificate(der1)
if err != nil {
return err
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Treat the sentinel as expected behavior — re-issue or fetch the certificate that actually reuses the same public key
- Log via LogNonPubKeyMismatchErr only for other errors; skip handling for this one (errors.Is(err, ErrPubKeyMismatch))
- Verify you loaded the intended certificate files (wrong file/path mixups are common)
- If key reuse is required (e.g. after CA migration), re-sign the CSR of the original key instead of using a new key
Example fix
// before
if err != nil { log.Fatal(err) }
// after
if errors.Is(err, crypto.ErrPubKeyMismatch) {
// benign: certs use different keys
return
} Defensive patterns
Strategy: try-catch
Type guard
func isPubKeyMismatch(err error) bool { return errors.Is(err, crypto.ErrPubKeyMismatch) } Try / catch
if err != nil {
if errors.Is(err, crypto.ErrPubKeyMismatch) {
// benign mismatch, continue
} else {
crypto.LogNonPubKeyMismatchErr(log, err, der1, der2)
}
} Prevention
- Use errors.Is against the sentinel instead of string matching
- Route all non-mismatch errors through LogNonPubKeyMismatchErr
- Track certificate rotations so key-reuse expectations stay accurate
When it happens
Trigger: Calling CertificatesWithSamePublicKey (or TestCertificatesWithSamePublicKey) with two DER certificates whose public keys differ; the function compares parsed public keys and returns this sentinel when they are not equal.
Common situations: Certificate rotation replaced a cert with a new key while gossip/tls code expected key-material reuse; comparing certs from different CAs/identities; remediation logic for CVE-2020-7919 style key-collision checks where keys genuinely differ.
Related errors
- failed to PEM decode identity bytes: %s
- failed parsing certificate %s
- failed deserializing signed data identity during channelless
- parseCertificate failed
- enrollment certificate is not a valid x509 certificate: %v
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/f4ed5cdb98233fa2.
Report an issue: GitHub.