Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Linux Admins By James Joyner IV · · 9 min read Last reviewed Jul 2026

Linux Error Guide: 'unsigned module loading is restricted' — Sign or Enroll Your MOK Key

Quick answer

Fix kernel lockdown and Secure Boot module signature errors on Linux by signing out-of-tree modules, enrolling a MOK key, and configuring DKMS signing.

  • #linux
  • #troubleshooting
  • #errors
  • #secure-boot
Free toolkit

Stuck on this Linux Admins error? Get the free incident triage checklist

A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.

Overview

Linux kernel lockdown and Secure Boot module signature enforcement prevent unsigned or untrusted kernel modules from loading at runtime. When Secure Boot is active and the system’s Module Signature Enforcement policy is in effect, attempting to insert an out-of-tree or self-compiled module fails with errors like these:

Lockdown: modprobe: unsigned module loading is restricted; see man kernel_lockdown.7
modprobe: ERROR: could not insert 'wireguard': Key was rejected by service
Loading of unsigned module is rejected

The Key was rejected by service message comes from the kernel’s keyring subsystem: the module is not signed with a key that the running kernel trusts. The lockdown message indicates the kernel is in confidentiality or integrity lockdown mode, which imposes additional restrictions beyond standard module signing. Resolving these errors requires either signing the module with a trusted key, enrolling a new Machine Owner Key (MOK) via shim’s MokManager, or — as a last resort — disabling Secure Boot.

Symptoms

  • modprobe <module> or insmod <module>.ko fails immediately after a kernel upgrade or on a new system with Secure Boot enabled.
  • dmesg shows Lockdown: or module verification failed lines.
  • DKMS modules (WireGuard, VirtualBox, NVIDIA, ZFS) that worked on a previous kernel fail after an upgrade because the new kernel was not in the DKMS signing configuration.
  • mokutil --sb-state confirms Secure Boot is enabled.
  • lsmod | grep <module> shows the module is absent even though the package appears installed.
  • The system boots into a degraded state because a required module (e.g., a network or storage driver) could not be loaded.

Common Root Causes

Secure Boot enabled with no enrolled MOK — the default shim + GRUB configuration on Ubuntu, Fedora, and RHEL signs the bootloader and kernel, but out-of-tree modules built by DKMS are not automatically signed unless a MOK has been enrolled and DKMS signing is configured.

Kernel upgraded, DKMS module not rebuilt — DKMS rebuilds modules against new kernel headers, but if the rebuilt module is not signed with the enrolled key it fails the keyring check on the new kernel.

CONFIG_MODULE_SIG_FORCE=y in the running kernel — this compile-time option makes signature enforcement mandatory with no bypass. Most distribution kernels paired with Secure Boot set this flag.

Kernel lockdown mode active — kernels compiled with CONFIG_SECURITY_LOCKDOWN_LSM=y can enter integrity or confidentiality lockdown when Secure Boot is active, blocking unsigned modules even when the standard module signing check would otherwise pass.

Self-compiled or vendor-supplied module without a distribution signature — third-party drivers (GPU drivers from NVIDIA’s .run installer, out-of-tree WireGuard backports on older kernels, custom hardware drivers) are not signed by the distribution’s kernel-signing key.

MOK database cleared or key expired — a firmware update, NVRAM reset, or accidental shim database clear removes previously enrolled MOK keys, invalidating signatures on modules that relied on them.

Diagnostic Workflow

First, confirm whether Secure Boot is active and whether lockdown is enforced:

mokutil --sb-state
cat /sys/kernel/security/lockdown

mokutil --sb-state prints SecureBoot enabled or SecureBoot disabled. The lockdown file returns none, integrity, or confidentiality. Integrity lockdown blocks unsigned modules; confidentiality lockdown is more restrictive.

Check the kernel log for the specific rejection reason:

dmesg | grep -i 'lockdown\|module.*verif\|signature\|rejected'
journalctl -k | grep -i 'module\|lockdown' | tail -30

Identify which modules failed and whether the kernel requires forced signing:

# Check compile-time config of the running kernel
grep -E 'CONFIG_MODULE_SIG|CONFIG_SECURITY_LOCKDOWN' /boot/config-$(uname -r)

CONFIG_MODULE_SIG_FORCE=y means signatures are mandatory. CONFIG_MODULE_SIG=y without FORCE means signatures are verified but unsigned modules may still load when not in lockdown.

List the keys the running kernel trusts:

keyctl list %:.builtin_trusted_keys
keyctl list %:.secondary_trusted_keys 2>/dev/null || true

List enrolled MOK keys:

mokutil --list-enrolled

If you have a signed module, verify its signature:

modinfo /lib/modules/$(uname -r)/extra/wireguard.ko | grep -E 'sig|signer|vermagic'

Example Root Cause Analysis

Scenario: After upgrading from Ubuntu 22.04 kernel 5.15.0-100 to 5.15.0-105, the WireGuard tunnel device fails to come up. dmesg shows:

modprobe: ERROR: could not insert 'wireguard': Key was rejected by service

Check the DKMS status:

dkms status
wireguard/1.0.20220627, 5.15.0-105-generic, x86_64: built

DKMS built the module against the new kernel but did not sign it. Confirm no signature is present:

modinfo /lib/modules/5.15.0-105-generic/updates/dkms/wireguard.ko | grep signer

No output — the module is unsigned. The fix is to create a MOK key pair, sign the module, and enroll the key.

Step 1 — Create a MOK key pair (skip if you already have one):

openssl req -new -x509 -newkey rsa:2048 -keyout /root/mok.key \
  -out /root/mok.crt -days 3650 -subj "/CN=Local MOK Signing Key/" -nodes

Step 2 — Sign the module:

/usr/src/linux-headers-$(uname -r)/scripts/sign-file \
  sha256 /root/mok.key /root/mok.crt \
  /lib/modules/$(uname -r)/updates/dkms/wireguard.ko

Step 3 — Convert the certificate and enroll it:

openssl x509 -in /root/mok.crt -outform DER -out /root/mok.der
mokutil --import /root/mok.der

mokutil prompts for a one-time password used to confirm enrollment in the next boot’s MokManager screen.

Step 4 — Reboot and enroll: On the next boot, shim launches MokManager (a blue UEFI screen). Select “Enroll MOK”, enter the password, confirm, and continue booting.

Step 5 — Verify and load:

mokutil --list-enrolled | grep -i "local mok"
modprobe wireguard
dmesg | grep -i wireguard

The module loads without error.

Configuring DKMS to sign automatically so future DKMS rebuilds are signed without manual intervention:

# /etc/dkms/framework.conf
mok_signing_key="/root/mok.key"
mok_certificate="/root/mok.crt"
sign_tool="/usr/src/linux-headers-$(uname -r)/scripts/sign-file"

After setting this, every DKMS rebuild signs the module automatically.

Prevention Best Practices

  • Enroll a MOK key and configure DKMS signing (/etc/dkms/framework.conf) before installing any out-of-tree module. This makes all future DKMS rebuilds sign automatically.
  • Store the MOK private key (mok.key) and certificate (mok.crt) in a secure, backed-up location outside /tmp. Losing the key means re-enrolling after any MOK database clear.
  • Test module loading immediately after each kernel upgrade in a staging environment before upgrading production. Run dkms status to confirm all modules are built and signed.
  • In CI pipelines that build custom modules, include a modinfo | grep signer check to verify the signature is present in the artifact.
  • On systems where Secure Boot is not a requirement, disable it consistently in UEFI rather than leaving it in an ambiguous state where some modules load and others do not. Partial enforcement is harder to debug than a clear policy.
  • Monitor journalctl -k | grep -i 'module.*reject\|lockdown' as part of post-boot health checks in configuration management (Ansible, Salt) so signature failures surface before a service tries to use the module.

Quick Command Reference

# Check Secure Boot state and lockdown level
mokutil --sb-state
cat /sys/kernel/security/lockdown

# Search kernel log for module rejection messages
dmesg | grep -i 'lockdown\|module.*verif\|rejected\|signature'

# List enrolled MOK keys
mokutil --list-enrolled

# Check kernel compile-time signing configuration
grep CONFIG_MODULE_SIG /boot/config-$(uname -r)

# Generate a MOK key pair
openssl req -new -x509 -newkey rsa:2048 -keyout /root/mok.key \
  -out /root/mok.crt -days 3650 -subj "/CN=Local MOK/" -nodes

# Sign a module
/usr/src/linux-headers-$(uname -r)/scripts/sign-file \
  sha256 /root/mok.key /root/mok.crt /path/to/module.ko

# Import a MOK certificate for enrollment on next boot
openssl x509 -in /root/mok.crt -outform DER -out /root/mok.der
mokutil --import /root/mok.der

# Verify a module's signature
modinfo /path/to/module.ko | grep -E 'sig|signer'

# Check DKMS build status across all kernels
dkms status

Conclusion

Kernel lockdown and Secure Boot module signature enforcement protect the integrity of the running kernel, but they require explicit setup for out-of-tree modules. The resolution path is consistent: confirm Secure Boot and lockdown state with mokutil --sb-state and /sys/kernel/security/lockdown, identify the unsigned module with dmesg, generate a MOK key pair with openssl, sign the module using the kernel’s sign-file script, enroll the key with mokutil --import, and configure DKMS to sign automatically for future rebuilds. With DKMS signing configured and the MOK enrolled, kernel upgrades no longer break custom or vendor-supplied modules.

Free download · 368-page PDF

Fixed it? Get 500 Linux Admins & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Did this fix your issue?

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.