OpenVPN · DKMS
dkms "failed for ovpn-dco" after the kernel 7.0 update: your new kernel is fine
Published · HardStacked · 9 min
You updated Ubuntu 24.04 (its HWE kernel is now 7.0: 7.0.0-42 reached noble-updates on 2026-10-28) or Ubuntu 26.04, and apt stops with dkms autoinstall on 7.0.0-42-generic/aarch64 failed for ovpn-dco(10), then run-parts: /etc/kernel/header_postinst.d/dkms exited with return code 11. dpkg blames linux-headers-7.0.0-42-generic, and every apt command after that replays the error. An Ask Ubuntu question titled "something about openvpn is preventing my linux image from updating properly" (question 1570270, October 2026, kernel 7.0.0-38-generic, package ovpn-dco 0.2.20260526-1+26.1) shows the same errors as our test, and its build log shows a 24.04 toolchain (gcc-13 13.3.0-6ubuntu2~24.04.1).
Your new kernel is not broken. The culprit is openvpn-dco-dkms, a module that Linux has shipped in its own tree since 6.16 (the ovpn module). Removing that one package repairs apt. What decides afterwards whether your tunnel keeps data channel offload (DCO) is no longer a module to compile, it is the OpenVPN version.
The one answer to that question (score -1, not accepted) says to boot an older kernel, purge the new kernel, purge openvpn3-client, openvpn, openvpn-dco-dkms and the NetworkManager OpenVPN plugins, then reinstall the kernel. It costs you the kernel and the whole VPN stack to get rid of one package. We measured that one package is enough.
Measured on fresh Ubuntu 24.04.5 LTS and Ubuntu 26.04.1 LTS virtual machines (arm64, official cloud images), on 2026-11-10. Before the 24.04 capture the machine had Ubuntu's openvpn and openvpn-dco-dkms installed on kernel 6.8, which is probably your starting point.
01. What apt says, and what actually failed
Starting state, then the upgrade to the 7.0 HWE kernel. We cut download and unpacking lines, firmware packages and debconf noise, never a command.
the upgrade that breaks
$ grep PRETTY_NAME /etc/os-release
PRETTY_NAME="Ubuntu 24.04.5 LTS"
$ uname -r
6.8.0-147-generic
$ dpkg-query -W openvpn openvpn-dco-dkms
openvpn 2.6.19-0ubuntu0.24.04.5
openvpn-dco-dkms 0.0+git20231103-1ubuntu1.2
$ dkms status
ovpn-dco/0.0+git20231103, 6.8.0-147-generic, aarch64: installed
$ sudo apt-get install -y linux-generic-hwe-24.04
...
Setting up linux-headers-7.0.0-42-generic (7.0.0-42.42~24.04.1) ...
/etc/kernel/header_postinst.d/dkms:
* dkms: running auto installation service for kernel 7.0.0-42-generic
Building module:
Cleaning build area...(bad exit status: 2)
Error! Bad return status for module build on kernel: 7.0.0-42-generic (aarch64)
dkms autoinstall on 7.0.0-42-generic/aarch64 failed for ovpn-dco(10)
run-parts: /etc/kernel/header_postinst.d/dkms exited with return code 11
dpkg: error processing package linux-headers-7.0.0-42-generic (--configure):
installed linux-headers-7.0.0-42-generic package post-installation script subprocess returned error exit status 11
...
Setting up linux-image-7.0.0-42-generic (7.0.0-42.42~24.04.1) ...
I: /boot/vmlinuz is now a symlink to vmlinuz-7.0.0-42-generic
I: /boot/initrd.img is now a symlink to initrd.img-7.0.0-42-generic
...
run-parts: /etc/kernel/postinst.d/dkms exited with return code 11
dpkg: error processing package linux-image-7.0.0-42-generic (--configure):
installed linux-image-7.0.0-42-generic package post-installation script subprocess returned error exit status 11
Errors were encountered while processing:
linux-headers-7.0.0-42-generic
linux-headers-generic-hwe-24.04
linux-generic-hwe-24.04
linux-image-7.0.0-42-generic
E: Sub-process /usr/bin/dpkg returned an error code (1)
First liar: dpkg names the headers and the HWE meta-packages. The kernel image was unpacked and set up (look at the /boot/vmlinuz and initrd.img lines), then the same DKMS hook ran again from its trigger and failed again. On another run of ours the image configured fine, so read it as: dpkg may also list the kernel image. In both cases the failing thing is the hook, not the kernel.
02. Your new kernel already has the module
Ask dpkg what is stuck, read the build log, then ask the new kernel, even though you have not booted it (modinfo -k).
$ sudo dpkg --audit
The following packages are only half configured, probably due to problems
configuring them the first time. The configuration should be retried using
dpkg --configure <package> or the configure menu option in dselect:
linux-headers-7.0.0-42-generic Linux kernel headers for version 7.0.0
linux-image-7.0.0-42-generic Signed kernel image generic
$ dkms status
ovpn-dco/0.0+git20231103, 6.8.0-147-generic, aarch64: installed
$ grep -m2 'error:' /var/lib/dkms/ovpn-dco/*/build/make.log
drivers/net/ovpn-dco/tcp.c:482:31: error: assignment to ‘int (*)(struct sock *, struct msghdr *, size_t, int)’ {aka ‘int (*)(struct sock *, struct msghdr *, long unsigned int, int)’} from incompatible pointer type ‘int (*)(struct sock *, struct msghdr *, size_t, int, int *)’ {aka ‘int (*)(struct sock *, struct msghdr *, long unsigned int, int, int *)’} [-Werror=incompatible-pointer-types]
drivers/net/ovpn-dco/udp.c:346:51: error: passing argument 2 of ‘setup_udp_tunnel_sock’ from incompatible pointer type [-Werror=incompatible-pointer-types]
$ k=$(ls -v /lib/modules | tail -1); echo "$k"
7.0.0-42-generic
$ modinfo -k "$k" -F intree ovpn
Y
$ modinfo -k "$k" -n ovpn
/lib/modules/7.0.0-42-generic/kernel/drivers/net/ovpn/ovpn.ko.zst
The two compile errors are the same as in the Ask Ubuntu question (we are on arm64, they are on x86_64, same source code). The old out-of-tree driver calls kernel functions whose signatures changed. And intree Y: kernel 7.0 ships its own ovpn, in kernel/drivers/net/ovpn/. The package is trying to build a second copy of something the kernel already has.
03. Fix apt: remove one package
the fix
$ sudo apt-get purge -y openvpn-dco-dkms
...
The following package was automatically installed and is no longer required:
dkms
Use 'sudo apt autoremove' to remove it.
The following packages will be REMOVED:
openvpn-dco-dkms*
0 upgraded, 0 newly installed, 1 to remove and 42 not upgraded.
4 not fully installed or removed.
...
Removing openvpn-dco-dkms (0.0+git20231103-1ubuntu1.2) ...
...
Setting up linux-image-7.0.0-42-generic (7.0.0-42.42~24.04.1) ...
Setting up linux-headers-7.0.0-42-generic (7.0.0-42.42~24.04.1) ...
/etc/kernel/header_postinst.d/dkms:
* dkms: running auto installation service for kernel 7.0.0-42-generic
* dkms: autoinstall for kernel 7.0.0-42-generic
...done.
Setting up linux-headers-generic-hwe-24.04 (7.0.0-42.42~24.04.1) ...
Setting up linux-generic-hwe-24.04 (7.0.0-42.42~24.04.1) ...
...
$ sudo dpkg --configure -a
$ sudo dpkg --audit && echo "dpkg: nothing left half-configured"
dpkg: nothing left half-configured
$ dkms status
$ dpkg-query -W openvpn "linux-image-$k" "linux-headers-$k"
linux-headers-7.0.0-42-generic 7.0.0-42.42~24.04.1
linux-image-7.0.0-42-generic 7.0.0-42.42~24.04.1
openvpn 2.6.19-0ubuntu0.24.04.5
The purge finishes the kernel configuration by itself: you see Setting up linux-image-…, Setting up linux-headers-… and dkms: autoinstall … done, once the broken hook has nothing left to build. So dpkg --configure -a prints nothing, nothing left to do, which is the point. Keep it anyway as a safety net. The audit is clean, dkms status is empty, and the kernel and OpenVPN are still installed. Note that the purge also deletes the module built for the old 6.8 kernel. apt now offers to autoremove dkms itself, your call.
04. After the reboot: does your tunnel still use DCO?
We run sudo reboot, then load the kernel's module by hand and ask OpenVPN 2.6, the version Ubuntu 24.04 ships:
after the reboot
$ uname -r
7.0.0-42-generic
$ sudo modprobe ovpn
$ lsmod | grep -w '^ovpn'
ovpn 98304 0
$ openvpn --version | grep -E '^OpenVPN|DCO version'
OpenVPN 2.6.19 aarch64-unknown-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] [DCO]
DCO version: N/A
Second liar. The module is loaded and OpenVPN 2.6 still says DCO version: N/A. We then ran a real tunnel (two network namespaces, a throwaway PKI). The client log says Note: Kernel support for ovpn-dco missing, disabling data channel offload., while modinfo says the support is there. OpenVPN 2.6 looks for the old out-of-tree module and does not know how to talk to the new one. OpenVPN's README.dco lists this very message for when the kernel module is not usable. The tunnel comes up anyway, without DCO: ip -d link shows an interface of type tun.
According to the OpenVPN project (blog post "openvpn-dco-added-to-linux-kernel-2025"), DCO went into the official Linux kernel starting with 6.16, and their README.dco says the in-kernel ovpn module only works with OpenVPN 2.7 and later. For older kernels they point to a separate backports project (ovpn-backports). Ubuntu's versions, read on Launchpad on 2026-11-10: 24.04 has openvpn 2.6.19, 26.04 has 2.7.0.
So on 24.04 you have two choices. Live without DCO, the tunnel works. Or move to OpenVPN 2.7: we measured 2.7.9 from the isv:OpenVPN repository on the openSUSE Build Service, which publishes OpenVPN 2.7 for Ubuntu 24.04 (we did not check who maintains it, so we do not give the commands to add it). With it, the log says DCO version: 7.0.0-42-generic #42~24.04.1-Ubuntu ..., then DCO device tun0 opened, and the interface type is ovpn.
Last surprise, the one that stops the "just update the DKMS" reflex. The same repository also ships a recent openvpn-dco-dkms (0.2.20261109, a snapshot dated 2026-11-09 by its version number). It does compile on 7.0, with no error. But OpenVPN 2.7.9 never loads it: modinfo -n ovpn returns /lib/modules/7.0.0-42-generic/kernel/drivers/net/ovpn/ovpn.ko.zst, the kernel's module, and the DKMS built an ovpn-dco-v2.ko.zst that stays unused. Even when it compiles, the package is useless on 7.0.
The +26.1 suffix of the package in the question looks like the form used by that repository's packages on the openSUSE Build Service (isv:OpenVPN). That is an inference.
05. On Ubuntu 26.04, the package fails on install
26.04 already runs kernel 7.0, so the DKMS package fails the moment you install it:
Ubuntu 26.04
$ grep PRETTY_NAME /etc/os-release
PRETTY_NAME="Ubuntu 26.04.1 LTS"
$ uname -r
7.0.0-38-generic
$ sudo apt-get install -y openvpn openvpn-dco-dkms
...
Setting up openvpn (2.7.0-1ubuntu1.4) ...
...
Setting up openvpn-dco-dkms (0.0+git20251017-1) ...
Building for 7.0.0-38-generic
Error! Bad return status for module build on kernel: 7.0.0-38-generic (aarch64)
dpkg: error processing package openvpn-dco-dkms (--configure):
old openvpn-dco-dkms package postinst maintainer script subprocess failed with exit status 10
...
E: Sub-process /usr/bin/dpkg returned an error code (1)
$ sudo dpkg --audit
The following packages are only half configured, probably due to problems
configuring them the first time. The configuration should be retried using
dpkg --configure <package> or the configure menu option in dselect:
openvpn-dco-dkms DCO (Data-Channel Offload) kernel module for OpenVPN 2.6
$ sudo apt-get purge -y openvpn-dco-dkms
...
Removing openvpn-dco-dkms (0.0+git20251017-1) ...
Deleting module ovpn-dco/0.0+git20251017 completely from the DKMS tree.
...
$ sudo dpkg --audit && echo "dpkg: nothing left half-configured"
dpkg: nothing left half-configured
$ sudo modprobe ovpn
$ openvpn --version | grep -E '^OpenVPN|DCO version'
OpenVPN 2.7.0 aarch64-unknown-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] [DCO]
DCO version: 7.0.0-38-generic #38-Ubuntu SMP PREEMPT_DYNAMIC Fri Sep 4 09:28:02 UTC 2026
Look at the description in dpkg --audit: "for OpenVPN 2.6", on a release that ships OpenVPN 2.7. The package is obsolete and Ubuntu still ships it. Here nothing is lost by removing it: OpenVPN 2.7.0 talks to the kernel's module. In a real tunnel on another fresh 26.04 machine of ours the log says DCO version: 7.0.0-38-generic ... then DCO device tun0 opened, interface type ovpn, after the purge and with no option set.
06. What we did not measure
x86_64: our machines are arm64, the compile errors are the same as in the question, so we infer the same source code fails the same way. Secure Boot and MOK enrolment, the NetworkManager OpenVPN plugin and openvpn3-linux: not measured, and the Ask Ubuntu answer purges them too. Debian 13: not measured. It keeps a 6.12 kernel, so the DKMS package should stay useful there (inferred from the kernel version). Throughput and latency with and without DCO: we did not measure those and say nothing about them.
Same family, another OpenVPN trap: OpenVPN "CA signature digest algorithm too weak" when your CA is SHA-256.