slackhq/nebula · error
no certificate
Error message
no certificate
What it means
CAPool.VerifyCertificate returns the plain error 'no certificate' when the passed Certificate is nil. Verification cannot proceed without a certificate, and the nil check short-circuits before any fingerprinting or chain validation.
Source
Thrown at cert/ca_pool.go:159
ncp.certBlocklist = make(map[string]struct{})
}
// IsBlocklisted tests the provided fingerprint against the pools blocklist.
// Returns true if the fingerprint is blocked.
func (ncp *CAPool) IsBlocklisted(fingerprint string) bool {
if _, ok := ncp.certBlocklist[fingerprint]; ok {
return true
}
return false
}
// VerifyCertificate verifies the certificate is valid and is signed by a trusted CA in the pool.
// If the certificate is valid then the returned CachedCertificate can be used in subsequent verification attempts
// to increase performance.
func (ncp *CAPool) VerifyCertificate(now time.Time, c Certificate) (*CachedCertificate, error) {
if c == nil {
return nil, fmt.Errorf("no certificate")
}
fp, err := c.Fingerprint()
if err != nil {
return nil, fmt.Errorf("could not calculate fingerprint to verify: %w", err)
}
signer, err := ncp.verify(c, now, fp, "")
if err != nil {
return nil, err
}
// Pre nebula v1.10.3 could generate signatures in either high or low s form and validation
// of signatures allowed for either. Nebula v1.10.3 and beyond clamps signature generation to low-s form
// but validation still allows for either. Since a change in the signature bytes affects the fingerprint, we
// need to test both forms until such a time comes that we enforce low-s form on signature validation.
fp2, err := CalculateAlternateFingerprint(c)
if err != nil {
return nil, fmt.Errorf("could not calculate alternate fingerprint to verify: %w", err)View on GitHub (pinned to dd8f660c0a)
Solutions
- Check the certificate for nil before calling VerifyCertificate
- Handle errors from the certificate parsing/decoding step so a nil cert is never passed
- Log and reject the connection early when no peer certificate is available
Example fix
// before
cc, err := pool.VerifyCertificate(now, parsedCert) // parsedCert may be nil
// after
if parsedCert == nil {
return fmt.Errorf("peer did not present a certificate")
}
cc, err := pool.VerifyCertificate(now, parsedCert) Defensive patterns
Strategy: type-guard
Validate before calling
if c == nil {
return fmt.Errorf("no peer certificate available for verification")
}
_, err := pool.VerifyCertificate(now, c) Type guard
func hasCertificate(c cert.Certificate) bool {
return c != nil
} Try / catch
cc, err := pool.VerifyCertificate(now, c)
if err != nil {
if err.Error() == "no certificate" {
log.Warn("peer presented no certificate; rejecting handshake")
return err
}
return err
} Prevention
- Always check parse/decode errors before using a Certificate variable
- Treat nil certificates from handshake caches as a hard rejection
- Fail closed: never skip verification when the certificate is missing
When it happens
Trigger: Calling VerifyCertificate(now, c) with c == nil — typically when a decoded certificate variable was never populated because PEM decoding or certificate parsing failed upstream.
Common situations: Ignoring errors from earlier ParseCertificate/PEM decode steps and passing the nil result on, or optional certificate lookups (e.g. from a handshake cache) returning nil.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- ErrNotCA
- ErrNotSelfSigned
- %s: %w
- could not calculate fingerprint for provided CA; error: %w;
- could not calculate fingerprint to verify: %w
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/5ea9bbede593fe05.
Report an issue: GitHub.