slackhq/nebula · error

pki: use of %s is not allowed in FIPS 140-only mode

Error message

pki: use of %s is not allowed in FIPS 140-only mode

What it means

When FIPS 140-only mode is enforced, certificates must use NIST P-256. During pki.cert parsing, each loaded certificate whose curve is not P256 causes this error naming the offending curve, blocking startup.

Source

Thrown at pki.go:341

		pubPathOrPEM = "<inline>"

	} else {
		rawCert, err = os.ReadFile(pubPathOrPEM)
		if err != nil {
			return nil, fmt.Errorf("unable to read pki.cert file %s: %s", pubPathOrPEM, err)
		}
	}

	var crt, v1, v2 cert.Certificate
	for {
		// Load the certificate
		crt, rawCert, err = loadCertificate(rawCert)
		if err != nil {
			return nil, err
		}

		if fips140.Enforced() && crt.Curve() != cert.Curve_P256 {
			return nil, fmt.Errorf("pki: use of %s is not allowed in FIPS 140-only mode", crt.Curve())
		}

		switch crt.Version() {
		case cert.Version1:
			if v1 != nil {
				return nil, fmt.Errorf("v1 certificate already found in pki.cert")
			}
			v1 = crt
		case cert.Version2:
			if v2 != nil {
				return nil, fmt.Errorf("v2 certificate already found in pki.cert")
			}
			v2 = crt
		default:
			return nil, fmt.Errorf("unknown certificate version %v", crt.Version())
		}

		if len(rawCert) == 0 || strings.TrimSpace(string(rawCert)) == "" {

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Re-issue the certificate (and CA) with P-256 key via `nebula-cert` and update pki.cert/ca.crt.
  2. Disable FIPS 140 enforcement if P-256 migration isn't possible and policy allows.
  3. Audit all certs in the pki.cert chain — every cert in the file must be P256 in FIPS mode.
  4. Note FIPS mode also forbids chachapoly ciphers; switch cipher to aes.

Example fix

# before
nebula-cert ca -name "My Org"   # defaults to 25519
# after
nebula-cert ca -name "My Org" -curve P256
nebula-cert sign -ca-crt ca.crt -ca-key ca.key -name host -ip 10.0.0.1/24 -curve P256
Defensive patterns

Strategy: validation

Validate before calling

// Before FIPS-mode rollout: verify all certs are P-256
func checkCurvesFIPS(chain []byte) error {
  rest := chain
  for len(rest) > 0 {
    var crt *x509.Certificate
    crt, rest, _ = parseOne(rest)
    if crt.Curve != elliptic.P256() {
      return fmt.Errorf("cert %s uses non-P256 curve; FIPS mode forbids it", crt.Subject)
    }
  }
  return nil
}

Try / catch

cs, err := newCertStateFromConfig(...)
if err != nil {
  if strings.Contains(err.Error(), "not allowed in FIPS 140-only mode") {
    return fmt.Errorf("re-issue certificates with -curve P256 before enabling FIPS enforcement: %w", err)
  }
  return err
}

Prevention

When it happens

Trigger: reloadCerts -> newCertStateFromConfig with fips140.Enforced() true and a certificate issued on Curve 25519 (or any non-P256 curve) in pki.cert.

Common situations: Running nebula under FIPS-enforced mode with pre-existing 25519 certificates; mixed fleets where certs were re-issued with curve 25519; testing FIPS mode against default-issued certs; distro/build with FIPS 140 enforcement enabled unexpectedly.

Related errors


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