Kernel version and kernel headers out of sync after kernel update

Creating a bug report/issue

[yes] I have searched the existing open and closed issues

Required Information

  • DietPi version | cat /boot/dietpi/.version

  • G_DIETPI_VERSION_CORE=9
    G_DIETPI_VERSION_SUB=11
    G_DIETPI_VERSION_RC=2
    G_GITBRANCH=‘master’
    G_GITOWNER=‘MichaIng’

  • Distro version | echo $G_DISTRO_NAME $G_RASPBIAN
    bookworm 0

  • Kernel version | uname --all
    Linux music-compiler 6.12.20+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.12.20-1+rpt1~bpo12+1 (2025-03-19) aarch64 GNU/Linux

  • Architecture | dpkg --print-architecture
    arm64

  • SBC model | echo $G_HW_MODEL_NAME or (EG: RPi3)
    RPi 4 Model B (aarch64)

  • Power supply used | (EG: 5V 1A RAVpower)
    DeskPi 12V power supply (case has 5V regulator)

  • SD card used | (EG: SanDisk ultra)
    Samsung Evo

Additional Information (if applicable)

  • Software title | (EG: Nextcloud)
  • Was the software title installed freshly or updated/migrated?
  • Can this issue be replicated on a fresh installation of DietPi?
    ← If you sent a “dietpi-bugreport”, please paste the ID here →
  • Bug report ID | echo $G_HW_UUID

Steps to reproduce

  1. Install package raspberrypi-kernel-headers
  2. Update DietPi to 9.11
  3. Update kernel to 6.12.20 through apt upgrade
  1. After following above steps kernel will be 6.12.20, but /usr/src/ will contain kernel headers for 6.1.21 still and won’t have updated to the version corresponding to the new kernel

Expected behaviour

Kernel headers package should be tracking the distribution kernel version

Actual behaviour

Kernel headers package is remaining on version for old kernel

We don’t maintain kernel or headers packages ourselves. They are original one from RPi repositories. Did you install a specific headers package manually?

No, I just installed the standard kernel headers package, not a specific version, which is why I’d expect that it would track with the kernel version itself.

Since 6.6 you need another package: linux-headers-rpi-v8

see:
https://dietpi.com/forum/t/kernel-headers-missing-build-folder-after-updating-to-9-10/22752/10?u=jappe
https://www.raspberrypi.com/documentation/computers/linux_kernel.html#kernel-headers

2 Likes

Thanks. That was exactly what I needed.

Of course now they’ve split out the headers into a common and an RPi-specific one then some compile paths that use $(uname -r) are now failing to properly resolve the anticipated headers, but that’s easy enough to work around.

Really? The mentioned headers package should be complete and have all relevant files linked to /lib/modules/$(uname -r)/build isn’t it?

In my case I needed to point to the header files, so I used to have an include statement like:
-I/usr/src/linux-headers-$(uname -r)/include/uapi

I’ve had to change this to:
-I/usr/src/linux-headers-$(uname -r | sed ‘s/-rpi-v8//g’)-common-rpi/include/uapi

which is kind of kludgey, but at least works for me for the moment,

Why not use -I /lib/modules/$(uname -r)/build/include/uapi? This is what this symlink is for, to assure you really use the headers for the exact kernel used.

The uapi directory doesn’t exist in this path.

What appears to have happened is that the various headers have been split across two paths: linux-headers-6.12.20+rpt-common-rpi and linux-headers-6.12.20+rpt-rpi-v8, so whereas you used to have a single path that was kernel-specific, they’ve now been separated out into a common Pi folder plus the V8 folder and the symlink is therefore only going to give you headers in the V8 folder.

I see it now, how annoying. Interestingly, /lib/modules/$(uname -r)/build points to the dir of the v8 package, and /lib/modules/$(uname -r)/source points to the dir of the common package. I always thought both symlinks would be equivalent, with build being the newer one commonly used, while source the older one, only present for compatibility reasons. But I was wrong.

It is quite fascinating how LLMs are able to give a reasonable answer without any further context:

What is the difference between “/lib/modules/$(uname -r)/source” and “/lib/modules/$(uname -r)/build”?

ChatGPT said:

Good question — it’s a subtle but important difference!

On a typical Linux system:

  • /lib/modules/$(uname -r)/source
    → This points to the full kernel source code for the currently running kernel ($(uname -r) expands to something like 5.15.0-91-generic).
    → It’s used when you actually need the entire kernel source tree — for example, if you are developing kernel modules that need access to internal headers, or patching the kernel itself.
  • /lib/modules/$(uname -r)/build
    → This points to the kernel build directory — typically the source tree plus the files/configuration generated during kernel compilation (like Makefile, .config, compiled .o files, etc.).
    → It’s mainly used for building external kernel modules. You usually need the build directory to compile a new kernel module against the currently running kernel.

:white_check_mark: In practice:

  • source → pure source code (sometimes installed separately via a linux-source package).
  • build → the prepared tree for building stuff (like out-of-tree modules); it includes enough info (headers, config, symlinks) to let you compile against the kernel.

Sometimes (especially on distros like Ubuntu), both /source and /build point to the same location via symlink, if they are installed together and identical.


Would you like me to also show a real-world example of what happens if one of them is missing? :rocket:

Often the headers packages ship/create build only, and this is what is used by DKMS etc when building kernel modules. So it seems like you need the whole source tree and should use -I /lib/modules/$(uname -r)/source/include/uapi as generic link instead. Other kernel header packages (Debian and Armbian) do not have those split, but obviously it is/was not so uncommon in other distros.

1 Like