slackhq/nebula · critical
ErrSignatureMismatch
ErrSignatureMismatch
Error message
certificate signature did not match
What it means
ErrSignatureMismatch is returned by verify (and asserted in cmd/nebula-cert verify tests) when the candidate certificate's signature cannot be verified against the selected CA signer's public key — the certificate was not genuinely signed by that CA or its bytes were altered.
Source
Thrown at cert/errors.go:16
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")
ErrNoPeerStaticKey = errors.New("no peer static key was present")View on GitHub (pinned to dd8f660c0a)
Solutions
- Ensure node certs are signed by the same CA whose cert is in the pool — regenerate the node cert with the current ca.key/ca.crt.
- Verify file integrity (re-copy ca.crt and node.crt, compare checksums).
- Confirm the pool used at verification is the same CA environment that issued the cert.
- In tests, use the matching test CA fixture for the certificate under test.
Example fix
// before // ca.crt from CA-A, node.crt signed by CA-B pool := cert.NewCAPoolFromBytes(caA) err := pool.VerifyCertificate(nodeB) // ErrSignatureMismatch // after pool := cert.NewCAPoolFromBytes(caB) // CA that actually signed nodeB err = pool.VerifyCertificate(nodeB)
Defensive patterns
Strategy: try-catch
Validate before calling
if !c.CheckSignature(ca.Certificate.PublicKey()) {
return fmt.Errorf("cert %s was not signed by the loaded CA", c.Name())
} Type guard
func signedByCA(c cert.Certificate, ca cert.Certificate) bool {
return c.CheckSignature(ca.Certificate.PublicKey())
} Try / catch
if _, err := pool.VerifyCertificate(c, "", ""); errors.Is(err, cert.ErrSignatureMismatch) {
return fmt.Errorf("cert/CA mismatch: re-sign the host cert with the deployed ca.crt")
} Prevention
- Sign and distribute node certs from the same CA environment used at runtime.
- Checksum-verify ca.crt and host.crt when deploying.
- Keep one CA per environment and label cert files accordingly.
When it happens
Trigger: pool.verify: c.CheckSignature(signer.Certificate.PublicKey()) returns false (cert/ca_pool.go:241). Also produced by the nebula-cert CLI verify subcommand when the checked cert/signature pair doesn't match.
Common situations: ca.crt and node.crt generated from different CAs (mixing environments); the certificate file was edited/corrupted in transit; re-signed cert distributed with the old CA file; mismatched v1/v2 handling.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- ErrNotSelfSigned
- ErrEmptySignature
- could not calculate alternate fingerprint to verify: %w
- ErrBadFormat
- ErrRootExpired
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/873cd15d0413f899.
Report an issue: GitHub.