slackhq/nebula · error

error while getting public key with PKCS#11: %w

Error message

error while getting public key with PKCS#11: %w

What it means

Wraps any failure from p11Client.GetPubKey() while running `nebula-cert ca` in PKCS#11 (-p11url) mode. The PKCS#11 client is created successfully but the HSM/token refused or failed to return the public key for the configured private key object. The underlying pkclient error is preserved via %w, so errors.Unwrap reveals the root cause.

Source

Thrown at cmd/nebula-cert/ca.go:266

	if isP11 {
		switch *cf.curve {
		case "P256":
			curve = cert.Curve_P256
		default:
			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)

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Check the wrapped error (errors.Unwrap / printed detail) for the exact PKCS#11 return code
  2. Verify the -p11url points to an existing key object on the correct token/slot
  3. Confirm the PKCS#11 module library path and that the token is present (pkcs11-tool -L)
  4. Re-authenticate: an expired/missing PIN or a locked session causes key lookups to fail

Example fix

// before
nebula-cert ca -p11url "pkcs11:token=mytoken;object=ca-key" -name "my ca"
// after
nebula-cert ca -p11url "pkcs11:token=mytoken;object=ca-key;pin=<correct-pin>&module-path=/usr/lib/softhsm/libsofthsm2.so" -name "my ca"
Defensive patterns

Strategy: try-catch

Validate before calling

// before running: confirm the token/key is reachable
// pkcs11-tool --module <module> -L   # list slots
// pkcs11-tool --module <module> -O   # list objects, verify 'ca-key' exists

Type guard

func isP11KeyLookupErr(err error) bool {
	return err != nil && strings.Contains(err.Error(), "error while getting public key with PKCS#11")
}

Try / catch

err := cmd.Run()
var p11Err *os.PathError
if err != nil && strings.Contains(err.Error(), "PKCS#11") {
	log.Printf("PKCS#11 key lookup failed: %v — check token, pin, and module path", err)
	return fmt.Errorf("HSM unavailable: %w", err)
}

Prevention

When it happens

Trigger: nebula-cert ca -p11url <pkcs11-url> where the URL's token/slot/pin is wrong, the referenced key object does not exist or is not accessible, the PKCS#11 module is missing/misconfigured, or the token is removed/locked between client creation and GetPubKey.

Common situations: HSM or smartcard not plugged in; wrong pin or slot pinned in the pkcs11 URL; key was deleted from the token; PKCS#11 module library path wrong or permissions deny access to the token device.

Related errors


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