slackhq/nebula · error
error while adding CA certificate to CA trust store: %s
Error message
error while adding CA certificate to CA trust store: %s
What it means
When cert.NewCAPoolFromPEMReader returns an error other than the tolerated ErrExpired, loadCAPoolFromConfig wraps it with this message. It means the pki.ca PEM stream contained data that could not be added to the trust store — malformed PEM blocks or unparsable certificates.
Source
Thrown at pki.go:574
}
defer caReader.Close()
caPool, err := cert.NewCAPoolFromPEMReader(caReader)
if errors.Is(err, cert.ErrExpired) {
var expired int
for _, crt := range caPool.CAs {
if crt.Certificate.Expired(time.Now()) {
expired++
l.Warn("expired certificate present in CA pool", "cert", crt)
}
}
if expired >= len(caPool.CAs) {
return nil, errors.New("no valid CA certificates present")
}
} else if err != nil {
return nil, fmt.Errorf("error while adding CA certificate to CA trust store: %s", err)
}
bl := c.GetStringSlice("pki.blocklist", []string{})
if len(bl) > 0 {
for _, fp := range bl {
caPool.BlocklistFingerprint(fp)
}
l.Info("Blocklisted certificates", "fingerprintCount", len(bl))
}
return caPool, nil
}
View on GitHub (pinned to dd8f660c0a)
Solutions
- Regenerate or re-export ca.crt with 'nebula-cert ca' and ensure it contains only valid Nebula CA certificate PEM blocks
- Remove non-certificate PEM blocks (private keys, unrelated certs) from the file
- Validate the file with 'nebula-cert print -path ca.crt'
- If expired CAs were intended to be skipped, rely on the built-in expired-skipping rather than fixing via this path — this error is for unparsable data, not expiry
Example fix
// before pki.ca contains: host key block + CA cert block concatenated // after pki.ca contains only: -----BEGIN NEBULA CERTIFICATE----- ... (CA cert)
Defensive patterns
Strategy: validation
Validate before calling
f, _ := os.Open(caPath)
defer f.Close()
if _, err := cert.NewCAPoolFromPEMReader(f); err != nil && !errors.Is(err, cert.ErrExpired) {
return fmt.Errorf("invalid pki.ca: %w", err)
} Type guard
func caPEMValid(b []byte) bool {
blk, _ := pem.Decode(b)
return blk != nil && strings.Contains(blk.Type, "CERTIFICATE")
} Try / catch
pool, err := loadCAPoolFromConfig(logger, cfg)
if err != nil && strings.Contains(err.Error(), "CA trust store") {
return fmt.Errorf("pki.ca contains unparsable data: %w", err)
} Prevention
- Keep pki.ca containing only Nebula CA certificate PEM blocks
- Validate with 'nebula-cert print' before deployment
- Never concatenate private keys or foreign PEM into pki.ca
- Generate CAs only with nebula-cert to ensure format compatibility
When it happens
Trigger: reloadCAPool reads a pki.ca whose PEM contains invalid base64, non-certificate blocks, a cert format the parser rejects, or trailing garbage that fails decoding.
Common situations: CA file manually concatenated with other PEM material (keys, intermediate chains in wrong format); copy/paste corruption of inline PEM; CA generated by an incompatible tool/version.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- no pki.ca path or PEM data provided
- can not sign a CA certificate with another
- v1 certificate already found in pki.cert
- v2 certificate already found in pki.cert
- error while unmarshaling pki.cert: %w
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/ded4a7140d30bbf1.
Report an issue: GitHub.