slackhq/nebula · error
use of Curve25519 is not allowed in FIPS 140-only mode
Error message
use of Curve25519 is not allowed in FIPS 140-only mode
What it means
In cmd/nebula-cert/ca.go (ca), when generating a CA with a Curve25519 curve ('25519', 'X25519', 'Curve25519', 'CURVE25519') and FIPS 140-only mode is enforced (fips140.Enforced()), the tool refuses to proceed. FIPS-only mode disallows non-approved algorithms, and Curve25519/X25519 is not FIPS-approved, so CA key generation is blocked deliberately.
Source
Thrown at cmd/nebula-cert/ca.go:272
return fmt.Errorf("invalid curve for PKCS#11: %s", *cf.curve)
}
p11Client, err = pkclient.FromUrl(*cf.p11url)
if err != nil {
return fmt.Errorf("error while creating PKCS#11 client: %w", err)
}
defer func(client *pkclient.PKClient) {
_ = client.Close()
}(p11Client)
pub, err = p11Client.GetPubKey()
if err != nil {
return fmt.Errorf("error while getting public key with PKCS#11: %w", err)
}
} else {
switch *cf.curve {
case "25519", "X25519", "Curve25519", "CURVE25519":
if fips140.Enforced() {
return errors.New("use of Curve25519 is not allowed in FIPS 140-only mode")
}
curve = cert.Curve_CURVE25519
pub, rawPriv, err = ed25519.GenerateKey(rand.Reader)
if err != nil {
return fmt.Errorf("error while generating ed25519 keys: %s", err)
}
case "P256":
var key *ecdsa.PrivateKey
curve = cert.Curve_P256
key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return fmt.Errorf("error while generating ecdsa keys: %s", err)
}
// ecdh.PrivateKey lets us get at the encoded bytes, even though
// we aren't using ECDH here.
eKey, err := key.ECDH()
if err != nil {View on GitHub (pinned to dd8f660c0a)
Solutions
- Generate the CA with a FIPS-approved curve instead: pass -curve P256.
- If 25519 is required, run without FIPS 140-only enforcement (remove fips140=only GODEBUG / use a non-FIPS build).
- Reuse an existing FIPS-compliant CA and only sign new certs with P256.
- Update organizational policy/config to declare the approved curve explicitly.
Example fix
// before $ nebula-cert ca -curve 25519 // after $ nebula-cert ca -curve P256
Defensive patterns
Strategy: validation
Validate before calling
if fips140.Enforced() {
if curve == "25519" || curve == "X25519" || curve == "Curve25519" || curve == "CURVE25519" {
return fmt.Errorf("curve %s unavailable under FIPS 140-only mode; use P256", curve)
}
}
return nebulaCertCA(curve) Type guard
func fipsAllowedCurve(c string) bool {
switch c {
case "25519", "X25519", "Curve25519", "CURVE25519":
return !fips140.Enforced()
case "P256":
return true
}
return false
} Try / catch
err := runCA(args)
if errors.Is(err, errFipsCurve) /* or check message */ {
log.Println("FIPS mode: falling back to P256")
err = runCA(replaceCurve(args, "P256"))
} Prevention
- Detect FIPS enforcement at startup and fail fast with a clear curve policy.
- Standardize on P256 for FIPS-regulated deployments.
- Pin curve settings in config/templates per environment (FIPS vs non-FIPS).
- Document that Go FIPS 140-only mode forbids Curve25519 family primitives.
When it happens
Trigger: Running 'nebula-cert ca -curve 25519' (or any alias) while the binary/environment has FIPS 140 enforcement enabled (GODEBUG fips140=only / fips140.Enforced() true).
Common situations: Deploying nebula-cert on FIPS-mandated hosts (government/regulated environments) while reusing an existing 25519-based config; CI containers built with FIPS-only Go toolchains.
Related errors
- pki: use of Curve25519 is not allowed in FIPS 140-only mode
- use of Curve25519 is not allowed in FIPS 140-only mode
- use of Curve25519 is not allowed in FIPS 140-only mode
- pki: use of ChaChaPoly is not allowed in FIPS 140-only mode
- ErrAlreadySeen
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/f1773c987a131155.
Report an issue: GitHub.