slackhq/nebula · error
ErrFingerprintMismatch
ErrFingerprintMismatch
Error message
certificate fingerprint did not match
What it means
ErrFingerprintMismatch is returned by verify when the caller supplied an expected signer fingerprint and the fingerprint of the CA that actually signed the certificate does not equal it. This guards against trusting a different (possibly malicious) CA within the pool.
Source
Thrown at cert/errors.go:15
package cert
import (
"errors"
"fmt"
)
var (
ErrBadFormat = errors.New("bad wire format")
ErrRootExpired = errors.New("root certificate is expired")
ErrExpired = errors.New("certificate is expired")
ErrNotCA = errors.New("certificate is not a CA")
ErrNotSelfSigned = errors.New("certificate is not self-signed")
ErrBlockListed = errors.New("certificate is in the block list")
ErrFingerprintMismatch = errors.New("certificate fingerprint did not match")
ErrSignatureMismatch = errors.New("certificate signature did not match")
ErrInvalidPublicKey = errors.New("invalid public key")
ErrInvalidPrivateKey = errors.New("invalid private key")
ErrPublicPrivateCurveMismatch = errors.New("public key does not match private key curve")
ErrPublicPrivateKeyMismatch = errors.New("public key and private key are not a pair")
ErrPrivateKeyEncrypted = errors.New("private key must be decrypted")
ErrCaNotFound = errors.New("could not find ca for the certificate")
ErrUnknownVersion = errors.New("certificate version unrecognized")
ErrCertPubkeyPresent = errors.New("certificate has unexpected pubkey present")
ErrCurveMismatch = errors.New("certificate curve does not match CA")
ErrInvalidPEMBlock = errors.New("input did not contain a valid PEM encoded block")
ErrInvalidPEMCertificateBanner = errors.New("bytes did not contain a proper certificate banner")
ErrInvalidPEMX25519PublicKeyBanner = errors.New("bytes did not contain a proper X25519 public key banner")
ErrInvalidPEMX25519PrivateKeyBanner = errors.New("bytes did not contain a proper X25519 private key banner")
ErrInvalidPEMEd25519PublicKeyBanner = errors.New("bytes did not contain a proper Ed25519 public key banner")
ErrInvalidPEMEd25519PrivateKeyBanner = errors.New("bytes did not contain a proper Ed25519 private key banner")
View on GitHub (pinned to dd8f660c0a)
Solutions
- Compare the pinned fingerprint with the actual CA's Fingerprint value and update the config or the ca.crt so they agree.
- Re-sign the certificate with the CA whose fingerprint is pinned.
- Clear the fingerprint hint if pinning is not intended (only pass the expected fingerprint when you mean to pin).
- Print both fingerprints (expected vs signer.Fingerprint) when debugging to spot rotation drift.
Example fix
// before valid, err := pool.VerifyCertificate(c, oldCaFp, "") // CA was rotated // after newCaFp := hex.EncodeToString(currentCA.Fingerprint) valid, err := pool.VerifyCertificate(c, newCaFp, "")
Defensive patterns
Strategy: validation
Validate before calling
expectedFp := config.PinnedCAFingerprint
if expectedFp != "" && expectedFp != hex.EncodeToString(ca.Fingerprint) {
return fmt.Errorf("pinned CA fingerprint mismatch: update config after rotation")
} Type guard
func fingerprintMatches(signer *cert.CachedCertificate, expectedFp string) bool {
return expectedFp == "" || expectedFp == signer.Fingerprint
} Try / catch
if _, err := pool.VerifyCertificate(c, pinnedFp, ""); errors.Is(err, cert.ErrFingerprintMismatch) {
return fmt.Errorf("CA rotated? pinned fp %s != signer fp %s", pinnedFp, signer.Fingerprint)
} Prevention
- Update pinned fingerprints whenever ca.crt is rotated.
- Log both expected and actual fingerprints on mismatch.
- Only pass a fingerprint hint when you intentionally pin a specific CA.
When it happens
Trigger: CAPool.verify (cert/ca_pool.go:236) when len(signerFp) > 0 and the resolved signer's Fingerprint differs from the provided signerFp — i.e., VerifyCertificate was given a fingerprint hint that matches a different CA in the pool.
Common situations: The pinned CA fingerprint in config doesn't match the ca.crt actually distributed (stale ca.crt after rotation); multiple CAs in the pool and the wrong one signed the cert; copy/paste error in fingerprint configuration.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- ErrMissingDetails
- could not calculate fingerprint for provided CA; error: %w;
- could not calculate fingerprint to verify: %w
- could not calculate alternate fingerprint to verify: %w
- error computing issuer: %v
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/ae7843d4fd54a1c8.
Report an issue: GitHub.