GRUB ‘Premature End of File’ on amd-ucode.img: BTRFS, bees, and Calamares Fixes
Two bugs, one confusing error
When GRUB throws “premature end of file” at amd-ucode.img, it almost always comes from one of two places: the bees block-level deduplication daemon has processed your /boot files and left GRUB unable to read them, or a Calamares installer quirk on newer ISOs is double-loading microcode and confusing GRUB during startup. Similar symptoms, different causes, different fixes.
The bees deduplication problem
Bees (Best-Effort Extent-Same) is a userspace deduplication daemon for BTRFS. Unlike file-level dedupe tools, it operates at the raw block extent layer — it sees no boundary between /home and /boot. That’s usually fine for the kernel’s BTRFS driver, which supports shared extents natively. GRUB does not. Its BTRFS module is a stripped-down implementation, and when it tries to load a deduplicated amd-ucode.img, it hits an extent it can’t resolve and aborts.
This interaction is documented. The bees GitHub issue #249 traces exactly this failure, and the corresponding entry on the GNU GRUB bug list confirms GRUB’s BTRFS reader simply doesn’t handle deduplicated extents. Not a configuration error — a fundamental gap in GRUB’s BTRFS support.
Recovering from a broken boot
Start with the fallback initramfs entry in your GRUB menu. Most Arch-based distributions (Manjaro, EndeavourOS, plain Arch) generate one alongside the primary image, and GRUB can usually still read it even when the primary image has been deduplicated. Once you’re in a running system:
systemctl stop beesd
systemctl disable beesd
pacman -S linux amd-ucode
grub-mkconfig -o /boot/grub/grub.cfg
If the fallback won’t boot either, grab a live ISO, chroot into your installation, and run the same sequence. Reinstalling linux and amd-ucode regenerates both image files from scratch, replacing any deduplicated shared extents with normal independent ones that GRUB can read.
Keeping bees away from /boot
Stopping bees permanently is the blunt fix. If you want to keep it running, the cleanest solution is mounting /boot on a separate non-BTRFS partition — ext4 works fine — so bees never touches those files at all. Alternatively, configure bees to operate only on specific subvolumes rather than the whole filesystem root; the bees documentation covers subvolume scope configuration. At minimum, stop beesd manually before any kernel or microcode update.
The Calamares double-load problem
On fresh installs from newer ISOs using the Calamares installer, a different failure produces a similar-looking error. The GRUB log shows start_image() returned 0x8000000000000001 rather than a plain file error. The cause here is microcode being loaded twice: modern mkinitcpio hooks (and some dracut configurations) embed CPU microcode directly inside the initramfs image. Then, when grub-mkconfig runs, GRUB automatically prepends the standalone amd-ucode.img to the initrd line — loading the same microcode a second time. The conflict can cause GRUB to fail during the transition to the initrd.
The fix
Edit /etc/default/grub and add or modify this line:
GRUB_EARLY_INITRD_LINUX_STOCK=''
Setting it to an empty string tells GRUB not to automatically prepend stock microcode images to boot entries — appropriate when microcode is already embedded in the initramfs. Then regenerate the config:
grub-mkconfig -o /boot/grub/grub.cfg
On Debian/Ubuntu-based systems, update-grub does the same thing. This fix only makes sense if your initramfs actually includes microcode already. Verify with:
lsinitcpio -a /boot/initramfs-linux.img | grep microcode
If nothing comes back, your microcode is not embedded and you should leave GRUB_EARLY_INITRD_LINUX_STOCK alone.
Why GRUB keeps struggling with BTRFS
GRUB’s BTRFS module doesn’t implement the full feature set the kernel driver does. Compressed extents, certain RAID profiles, and shared extents from deduplication all rely on logic that lives in the kernel but not in GRUB’s reader. The BTRFS documentation is explicit that block-level deduplication produces shared extents as a core mechanism — GRUB was written before deduplication was a common use case and hasn’t caught up fully, as reflected in the ongoing GRUB bug tracker discussions.
Keeping /boot on a separate ext4 partition sidesteps this entire problem. GRUB reads a plain ext4 partition without issue, and your BTRFS root can use every feature it wants without GRUB ever needing to understand any of them. It’s a small inconvenience during setup that saves a lot of headaches later.
Quick diagnosis checklist
- Running bees or another block-level dedupe tool? Stop it, reinstall the kernel and microcode packages, regenerate GRUB config.
- Fresh Calamares install from a recent ISO on BTRFS? Check for the microcode double-load, verify with
lsinitcpio, and tryGRUB_EARLY_INITRD_LINUX_STOCK=''. - Neither of the above? Boot the fallback initramfs, then run
btrfs check --readonly /dev/sdXYto rule out underlying filesystem corruption before changing anything else.
Sources
- github.com
- lists.gnu.org
- wiki.archlinux.org
- btrfs.readthedocs.io
- gnu.org
- forum.endeavouros.com
- mail-archive.com
