slackhq/nebula · error
invalid curve: %s
Error message
invalid curve: %s
What it means
VerifyPrivateKey validates that a private key matches a CA certificate. The switch over curve only handles Curve_CURVE25519 and Curve_P256; any other curve value reaches this default branch. It means the caller passed a curve the library cannot verify, not that the key bytes are wrong.
Source
Thrown at cert/cert_v2.go:199
// the call to PublicKey below will panic slice bounds out of range otherwise
if len(key) != ed25519.PrivateKeySize {
return ErrInvalidPrivateKey
}
if !ed25519.PublicKey(c.publicKey).Equal(ed25519.PrivateKey(key).Public()) {
return ErrPublicPrivateKeyMismatch
}
case Curve_P256:
privkey, err := ecdh.P256().NewPrivateKey(key)
if err != nil {
return ErrInvalidPrivateKey
}
pub := privkey.PublicKey().Bytes()
if !bytes.Equal(pub, c.publicKey) {
return ErrPublicPrivateKeyMismatch
}
default:
return fmt.Errorf("invalid curve: %s", curve)
}
return nil
}
var pub []byte
switch curve {
case Curve_CURVE25519:
var err error
pub, err = curve25519.X25519(key, curve25519.Basepoint)
if err != nil {
return ErrInvalidPrivateKey
}
case Curve_P256:
privkey, err := ecdh.P256().NewPrivateKey(key)
if err != nil {
return ErrInvalidPrivateKey
}
pub = privkey.PublicKey().Bytes()View on GitHub (pinned to dd8f660c0a)
Solutions
- Only call VerifyPrivateKey with Curve_CURVE25519 or Curve_P256; check the curve value before calling.
- Ensure the certificate was produced by a compatible version of this library; re-generate certificates with supported curves.
- Re-serialize/re-parse the certificate with a current proto schema if the curve value came from decoding an unknown enum number.
Example fix
// before
err := caCert.VerifyPrivateKey(cert.Curve(3), keyBytes)
// after
if curve != cert.Curve_CURVE25519 && curve != cert.Curve_P256 {
return fmt.Errorf("unsupported curve %v", curve)
}
err := caCert.VerifyPrivateKey(curve, keyBytes) Defensive patterns
Strategy: validation
Validate before calling
if curve != cert.Curve_CURVE25519 && curve != cert.Curve_P256 {
return fmt.Errorf("curve %v unsupported by VerifyPrivateKey", curve)
}
err := caCert.VerifyPrivateKey(curve, keyBytes) Type guard
func supportedCurve(c cert.Curve) bool {
return c == cert.Curve_CURVE25519 || c == cert.Curve_P256
} Try / catch
if err := caCert.VerifyPrivateKey(curve, key); err != nil {
if strings.HasPrefix(err.Error(), "invalid curve:") {
return fmt.Errorf("unsupported curve %v; use CURVE25519 or P256", curve)
}
return err
} Prevention
- Only use curve values defined in the current proto schema you compiled against.
- Validate enum values after unmarshalling certificates from untrusted sources.
- Keep certificate generation and verification on the same library version.
When it happens
Trigger: Calling certificateV2.VerifyPrivateKey(curve, key) on a CA certificate with any Curve value other than Curve_CURVE25519 or Curve_P256 (e.g. an unmarshalled proto enum with an out-of-range or reserved value).
Common situations: Certificates deserialized from a newer/older protobuf with an unknown curve number, hand-constructed certificates in tests, or code that forwards a raw integer cast to Curve without checking.
Related errors
- ErrNotCA
- ErrInvalidPublicKey
- certificate curve %s does not match expected %s
- curve in cert and private key supplied don't match
- invalid curve: %s
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/e14680f26b126104.
Report an issue: GitHub.