slackhq/nebula · error

failed to load module library: %s

Error message

failed to load module library: %s

What it means

New() failed to load the PKCS#11 module shared library via p11.OpenModule(hsmPath); the original error is discarded and the path is reported with %s. The library throws this because the HSM vendor PKCS#11 library could not be dlopen'd (missing file, bad architecture, or missing dependencies).

Source

Thrown at pkclient/pkclient_cgo.go:33

type PKClient struct {
	module     p11.Module
	session    p11.Session
	id         []byte
	label      []byte
	privKeyObj p11.Object
	pubKeyObj  p11.Object
}

type ecdsaSignature struct {
	R, S *big.Int
}

// New tries to open a session with the HSM, select the slot and login to it
func New(hsmPath string, slotId uint, pin string, id string, label string) (*PKClient, error) {
	module, err := p11.OpenModule(hsmPath)
	if err != nil {
		return nil, fmt.Errorf("failed to load module library: %s", hsmPath)
	}

	slots, err := module.Slots()
	if err != nil {
		module.Destroy()
		return nil, err
	}

	// Try to open a session on the slot
	slotIdx := 0
	for i, slot := range slots {
		if slot.ID() == slotId {
			slotIdx = i
			break
		}
	}

	client := &PKClient{

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Verify hsmPath points to the real PKCS#11 library file (ldd/path check)
  2. Run `ldd <module.so>` to find missing transitive dependencies
  3. Match library architecture to the binary (64-bit vs 32-bit)
  4. Install the vendor PKCS#11 library (e.g. opensc, softhsm2, vendor SDK)
  5. Temporarily modify/strace the open call to capture the raw OS error since it is swallowed here

Example fix

// before
pkcs11_library: /usr/lib/libsofthsm2.so
// after (find the real path)
find / -name 'libsofthsm2.so*'
pkcs11_library: /usr/lib/softhsm/libsofthsm2.so
Defensive patterns

Strategy: validation

Validate before calling

// verify the module library exists and is loadable before New()
if _, err := os.Stat(hsmPath); err != nil {
    return fmt.Errorf("PKCS#11 module not found: %s", hsmPath)
}
if out, err := exec.Command("ldd", hsmPath).CombinedOutput(); err != nil || strings.Contains(string(out), "not found") {
    return fmt.Errorf("PKCS#11 module has missing deps:\n%s", out)
}

Try / catch

client, err := pkclient.New(hsmPath, slot, pin, id, label)
if err != nil && strings.Contains(err.Error(), "failed to load module library") {
    return fmt.Errorf("check hsmPath/architecture/deps for %s: %w", hsmPath, err)
}

Prevention

When it happens

Trigger: Calling New() with an hsmPath that does not exist, is not a valid shared library, has the wrong architecture (32/64-bit), or whose transitive dependencies are missing — the pkcs11 package returns CKR_FUNCTION/OS load error.

Common situations: Wrong path to the vendor .so/.dll in config; Linux binary using a module compiled for another platform; missing vendor runtime deps; using a Windows p11 library path on Linux or vice versa.

Related errors


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