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

  1. Treat the sentinel as expected behavior — re-issue or fetch the certificate that actually reuses the same public key
  2. Log via LogNonPubKeyMismatchErr only for other errors; skip handling for this one (errors.Is(err, ErrPubKeyMismatch))
  3. Verify you loaded the intended certificate files (wrong file/path mixups are common)
  4. 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

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


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