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
- Verify hsmPath points to the real PKCS#11 library file (ldd/path check)
- Run `ldd <module.so>` to find missing transitive dependencies
- Match library architecture to the binary (64-bit vs 32-bit)
- Install the vendor PKCS#11 library (e.g. opensc, softhsm2, vendor SDK)
- 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
- Resolve the module's absolute path in config
- Match 64-bit module with 64-bit binary
- Run ldd (or dumpbin) on the vendor .so/.dll before deploy
- Install vendor runtime dependencies on hosts
- Note the raw load error is swallowed; verify the path manually
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
- notImplemented
- error while creating PKCS#11 client: %w
- error while getting public key with PKCS#11: %w
- error while signing with PKCS#11: %w
- error while creating PKCS#11 client: %w
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/d9c8c249e0b19ba1.
Report an issue: GitHub.