slackhq/nebula · error

%s: %w

Error message

%s: %w

What it means

CAPool.AddCA rejects any certificate whose IsCA() flag is false, wrapping ErrNotCA with the certificate's name. Only CA certificates may be added to the CA pool; leaf/host certificates are signed by CAs and must not be trusted as signers.

Source

Thrown at cert/ca_pool.go:103

// Parsed certificates will be verified and must be a CA
func (ncp *CAPool) AddCAFromPEM(pemBytes []byte) ([]byte, error) {
	c, pemBytes, err := UnmarshalCertificateFromPEM(pemBytes)
	if err != nil {
		return pemBytes, err
	}

	err = ncp.AddCA(c)
	if err != nil {
		return pemBytes, err
	}

	return pemBytes, nil
}

// AddCA verifies a Nebula CA certificate and adds it to the pool.
func (ncp *CAPool) AddCA(c Certificate) error {
	if !c.IsCA() {
		return fmt.Errorf("%s: %w", c.Name(), ErrNotCA)
	}

	if !c.CheckSignature(c.PublicKey()) {
		return fmt.Errorf("%s: %w", c.Name(), ErrNotSelfSigned)
	}

	sum, err := c.Fingerprint()
	if err != nil {
		return fmt.Errorf("could not calculate fingerprint for provided CA; error: %w; %s", err, c.Name())
	}

	cc := &CachedCertificate{
		Certificate:    c,
		Fingerprint:    sum,
		InvertedGroups: make(map[string]struct{}),
	}

	for _, g := range c.Groups() {

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Pass the CA certificate (ca.crt content) instead of the host certificate (host.crt)
  2. Verify the certificate was generated with the CA role (IsCA true) via nebula-cert
  3. Check file ordering when concatenating PEMs so only CA certs end up in the pool

Example fix

// before
pool.AddCA(hostCert) // ErrNotCA
// after
pool.AddCA(caCert)
Defensive patterns

Strategy: validation

Validate before calling

func isCACert(c cert.Certificate) bool {
    return c != nil && c.IsCA()
}
// only call pool.AddCA when isCACert(c) is true

Type guard

func isCA(c cert.Certificate) bool {
    return c != nil && c.IsCA()
}

Try / catch

if err := pool.AddCA(c); err != nil {
    if errors.Is(err, cert.ErrNotCA) {
        log.Fatalf("%s is not a CA certificate; pass ca.crt instead of host cert", c.Name())
    }
    return err
}

Prevention

When it happens

Trigger: Calling AddCA (directly or via AddCAFromPEM / NewCAPoolFromPEMReader) with a Certificate that was issued as a host/client certificate rather than a CA certificate.

Common situations: Passing a node cert (e.g. from nebula.crt) where the CA cert (ca.crt) is expected, mixing up the two files when building the CA pool from PEM files.

Related errors


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/50039f2b363cd791. Report an issue: GitHub.