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
- Regenerate the certificate with nebula-cert sign / keygen so a valid key pair is embedded.
- Verify the key generation step succeeded and the public key was passed to the certificate builder before signing.
- Check that unmarshal used the correct certificate version path so the pubkey field is parsed.
- 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
- Always set details.PublicKey from a freshly generated keypair before signing.
- Validate() certificates immediately after unmarshal.
- Use the correct version-specific unmarshal path so the pubkey field parses.
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
- ErrNotCA
- ErrPublicKeyMismatch
- encoded IPs should be in pairs, an odd number was found
- encoded Subnets should be in pairs, an odd number was found
- invalid curve: %s
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/8c7283818a5aac81.
Report an issue: GitHub.