slackhq/nebula · error

ErrInvalidPublicKey

ErrInvalidPublicKey

Error message

invalid public key

What it means

ErrInvalidPublicKey is returned by the certificate validate step (v1 cert/cert_v1.go:336 and v2 cert/cert_v2.go:395) when the certificate carries an empty public key. A Nebula certificate must embed the host's Curve25519/ed25519 public key used for tunnel encryption.

Source

Thrown at cert/errors.go:17

package cert

import (
	"errors"
	"fmt"
)

var (
	ErrBadFormat                  = errors.New("bad wire format")
	ErrRootExpired                = errors.New("root certificate is expired")
	ErrExpired                    = errors.New("certificate is expired")
	ErrNotCA                      = errors.New("certificate is not a CA")
	ErrNotSelfSigned              = errors.New("certificate is not self-signed")
	ErrBlockListed                = errors.New("certificate is in the block list")
	ErrFingerprintMismatch        = errors.New("certificate fingerprint did not match")
	ErrSignatureMismatch          = errors.New("certificate signature did not match")
	ErrInvalidPublicKey           = errors.New("invalid public key")
	ErrInvalidPrivateKey          = errors.New("invalid private key")
	ErrPublicPrivateCurveMismatch = errors.New("public key does not match private key curve")
	ErrPublicPrivateKeyMismatch   = errors.New("public key and private key are not a pair")
	ErrPrivateKeyEncrypted        = errors.New("private key must be decrypted")
	ErrCaNotFound                 = errors.New("could not find ca for the certificate")
	ErrUnknownVersion             = errors.New("certificate version unrecognized")
	ErrCertPubkeyPresent          = errors.New("certificate has unexpected pubkey present")
	ErrCurveMismatch              = errors.New("certificate curve does not match CA")

	ErrInvalidPEMBlock                   = errors.New("input did not contain a valid PEM encoded block")
	ErrInvalidPEMCertificateBanner       = errors.New("bytes did not contain a proper certificate banner")
	ErrInvalidPEMX25519PublicKeyBanner   = errors.New("bytes did not contain a proper X25519 public key banner")
	ErrInvalidPEMX25519PrivateKeyBanner  = errors.New("bytes did not contain a proper X25519 private key banner")
	ErrInvalidPEMEd25519PublicKeyBanner  = errors.New("bytes did not contain a proper Ed25519 public key banner")
	ErrInvalidPEMEd25519PrivateKeyBanner = errors.New("bytes did not contain a proper Ed25519 private key banner")

	ErrNoPeerStaticKey = errors.New("no peer static key was present")
	ErrNoPayload       = errors.New("provided payload was empty")

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Regenerate the certificate with nebula-cert sign / keygen so a valid key pair is embedded.
  2. Verify the key generation step succeeded and the public key was passed to the certificate builder before signing.
  3. Check that unmarshal used the correct certificate version path so the pubkey field is parsed.
  4. Validate len(cert.PublicKey()) > 0 right after unmarshal to fail fast with a clearer message.

Example fix

// before
cert := cert.NewNebulaCertificate(details) // details.publicKey never set
cert.Sign(caKey)

// after
details.PublicKey = pubkeyFromKeypair // 32-byte curve25519 key
cert := cert.NewNebulaCertificate(details)
cert.Sign(caKey)
Defensive patterns

Strategy: validation

Validate before calling

if len(c.PublicKey()) == 0 {
    return fmt.Errorf("certificate %s has no embedded public key; re-sign with a keypair", c.Name())
}

Type guard

func hasPublicKey(c cert.Certificate) bool {
    return len(c.PublicKey()) > 0
}

Try / catch

if err := c.Validate(); errors.Is(err, cert.ErrInvalidPublicKey) {
    return fmt.Errorf("regenerate the certificate: public key missing")
}

Prevention

When it happens

Trigger: Calling validate on a certificate where len(publicKey) == 0 — typically a cert signed without a public key, or constructed/unmarshaled from malformed input that dropped the key field.

Common situations: Custom signing code creating certificates without embedding a public key; corrupted serialization stripping the key field; version mismatch where the key field is read from the wrong offset/field during unmarshal.

Related errors


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