slackhq/nebula · error

invalid certificate

Error message

invalid certificate

What it means

After building and signing the concrete certificate struct, SignWith asserts the result implements the Certificate interface via a type assertion c.(Certificate). If the concrete type does not satisfy the interface, it returns "invalid certificate". This indicates an internal inconsistency between the version-specific certificate type and the Certificate interface contract.

Source

Thrown at cert/sign.go:145

	if err != nil {
		return nil, err
	}

	if curve == Curve_P256 {
		sig, err = p256.Normalize(sig)
		if err != nil {
			return nil, err
		}
	}

	err = c.setSignature(sig)
	if err != nil {
		return nil, err
	}

	sc, ok := c.(Certificate)
	if !ok {
		return nil, fmt.Errorf("invalid certificate")
	}

	return sc, nil
}

func comparePrefix(a, b netip.Prefix) int {
	addr := a.Addr().Compare(b.Addr())
	if addr == 0 {
		return a.Bits() - b.Bits()
	}
	return addr
}

// findDuplicatePrefix returns an error if there is a duplicate prefix in the pre-sorted input slice sortedPrefixes
func findDuplicatePrefix(sortedPrefixes []netip.Prefix) error {
	if len(sortedPrefixes) < 2 {
		return nil
	}

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Ensure the concrete certificate type for the chosen version implements every method of the cert.Certificate interface.
  2. Rebuild against a consistent version of the nebula cert package (go mod tidy / go build) to remove stale vendored code.
  3. If you added a new version case in the switch, implement the full Certificate interface (Checksum, Marshal, Sign, Verify, etc.) for it.

Example fix

// before
type certificateV3 struct{ /* missing Checksum() */ }

// after
func (c *certificateV3) Checksum() []byte { return c.checksum }
// plus remaining Certificate interface methods
Defensive patterns

Strategy: type-guard

Validate before calling

var _ cert.Certificate = (*cert.NebulaCertificate)(nil) // compile-time interface check

Type guard

func asCertificate(c any) (cert.Certificate, bool) {
    sc, ok := c.(cert.Certificate)
    return sc, ok
}

Try / catch

root, err := cert.Sign(signer, key, t)
if err != nil && err.Error() == "invalid certificate" {
    // rebuild against a consistent cert package version
    return err
}

Prevention

When it happens

Trigger: The signed concrete certificate (e.g. certificateV1/certificateV2 built in the version switch) fails the Certificate interface assertion inside SignWith — effectively only reachable with a mismatched or partially implemented certificate type.

Common situations: Custom forks or vendored copies of the cert package where a new version-specific certificate struct was added without implementing all Certificate interface methods, or binary/ABI mismatch after partial library upgrades.

Understand the failure class

Related errors


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