slackhq/nebula · error
error while unmarshaling pki.cert: %w
Error message
error while unmarshaling pki.cert: %w
What it means
loadCertificate wraps failures from cert.UnmarshalCertificateFromPEM: the pki.cert PEM bytes could not be decoded into a Nebula certificate. The library throws it so config-time cert problems surface with the underlying parser error preserved via %w.
Source
Thrown at pki.go:522
return rawKey, cert.Curve_P256, true, nil
} else {
pemPrivateKey, err = os.ReadFile(privPathOrPEM)
if err != nil {
return nil, curve, false, fmt.Errorf("unable to read pki.key file %s: %s", privPathOrPEM, err)
}
rawKey, _, curve, err = cert.UnmarshalPrivateKeyFromPEM(pemPrivateKey)
if err != nil {
return nil, curve, false, fmt.Errorf("error while unmarshaling pki.key %s: %s", privPathOrPEM, err)
}
}
return
}
func loadCertificate(b []byte) (cert.Certificate, []byte, error) {
c, b, err := cert.UnmarshalCertificateFromPEM(b)
if err != nil {
return nil, b, fmt.Errorf("error while unmarshaling pki.cert: %w", err)
}
if c.Expired(time.Now()) {
return nil, b, fmt.Errorf("nebula certificate for this host is expired")
}
if len(c.Networks()) == 0 {
return nil, b, fmt.Errorf("no networks encoded in certificate")
}
if c.IsCA() {
return nil, b, fmt.Errorf("host certificate is a CA certificate")
}
return c, b, nil
}
func loadCAPoolFromConfig(l *slog.Logger, c *config.C) (*cert.CAPool, error) {View on GitHub (pinned to dd8f660c0a)
Solutions
- Confirm pki.cert contains a '-----BEGIN NEBULA ... CERTIFICATE-----' block for this host, not the CA cert
- Regenerate/re-export the certificate with a nebula-cert version compatible with this binary
- Re-transfer the file in binary-safe mode (scp) and check it is not truncated
- Run 'nebula-cert print' on the file to validate it parses outside nebula
Example fix
// before pki: cert: /etc/nebula/ca.crt # CA cert supplied as host cert // after pki: cert: /etc/nebula/host.crt # host certificate issued by the CA
Defensive patterns
Strategy: validation
Validate before calling
certBytes, err := os.ReadFile(cfg.PKI.Cert)
if err != nil { return err }
if !bytes.Contains(certBytes, []byte("-----BEGIN")) {
return fmt.Errorf("%s is not a PEM certificate", cfg.PKI.Cert)
} Type guard
func isPEMCertificate(b []byte) bool {
blk, _ := pem.Decode(b)
return blk != nil && strings.Contains(blk.Type, "CERTIFICATE")
} Try / catch
c, rest, err := cert.UnmarshalCertificateFromPEM(certBytes)
if err != nil {
return fmt.Errorf("error while unmarshaling pki.cert: %w", err)
} Prevention
- Keep ca.crt and host.crt distinct; template configs with correct paths
- Use 'nebula-cert print' to validate certs before deployment
- Transfer PEM files in text-safe mode to avoid truncation
- Match nebula-cert version to the nebula binary version
When it happens
Trigger: newCertStateFromConfig is called and pki.cert contains no valid PEM block, a non-certificate PEM type, data in a format the bundled cert library cannot parse (e.g. newer/older cert format version), or concatenated garbage around the PEM block.
Common situations: pki.cert points to the CA file or a public key instead of the host cert; cert issued by a newer nebula-cert version with an incompatible format; file truncated by bad transfer; whitespace/BOM corruption.
Related errors
- v1 certificate already found in pki.cert
- v2 certificate already found in pki.cert
- no networks encoded in certificate
- host certificate is a CA certificate
- error while adding CA certificate to CA trust store: %s
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/26f1beed8c4bdf27.
Report an issue: GitHub.