Hello everyone,
I’ve been trying to build a customized Fedora IoT Bootc image using Fedora 44 and package it into an ISO using image-builder (bootc-installer).
I managed to work around several build-time osbuild errors, but I have hit a wall during the actual Anaconda installation phase with a “malformed pax extension” error, and I’m hoping someone can point me in the right direction.
The Blocker
I successfully generate the ISO. It boots into Anaconda. However, right as the deployment starts (ostree container image deploy), Anaconda crashes with this error:
pyanaconda.modules.common.errors.installation.PayloadInstallationError: The command 'ostree container image deploy ...' exited with the code 1: error: Performing deployment: Importing: Parsing layer blob ...: Processing tar: Filtering tar stream: Copying entry: malformed pax extension
Here’s an image:
From what I got from Gemini, this is likely due to modern OCI/Podman layer metadata (PAX headers) that the installer’s ostree or libarchive cannot parse. To fix this, I tried using the CoreOS Chunkah to normalize the layers, but the installation still fails.
My Setup
Here is my payload Containerfile (using the chunkah trick):
FROM quay.io/fedora/fedora-bootc:44 as rootfs-builder
# Idk, why but `ssh-key-dir/d` is not found, is this a bug?
RUN find /usr/share/doc/bootc-base-imagectl/manifests/ -type f -exec sed -i '/ssh-key-dir/d' {} +
# Use Fedora IoT manifest to build rootfs.
# https://docs.fedoraproject.org/en-US/iot/fedora-iot-bootc-pmachine-example/
RUN /usr/libexec/bootc-base-imagectl build-rootfs --manifest=fedora-iot /target-rootfs
FROM scratch as fedora-iot
COPY --from=rootfs-builder /target-rootfs/ /
LABEL containers.bootc 1
STOPSIGNAL SIGRTMIN+3
ENV fedora_version=44
CMD ["/sbin/init"]
FROM fedora-iot as fedora-iot-opinionated
# Enable faster downloads & DNF5 optimizations
RUN echo -e "[main]\nfastestmirror=True\nmax_parallel_downloads=10" > /etc/dnf/dnf.conf
# Add `machinectl` for Quadlets.
RUN --mount=type=cache,target=/var/cache/libdnf5 \
dnf5 -y install systemd-container
# Set up SSH Server to only accept SSH key logins.
ADD config/override_pubkey_authentication.conf /etc/ssh/sshd_config.d/override_pubkey_authentication.conf
# Change shell to Nushell.
RUN --mount=type=cache,target=/var/cache/libdnf5 \
dnf5 -y install 'dnf5-command(copr)' && \
dnf5 -y copr enable atim/nushell && \
dnf5 -y install nushell
RUN echo "/usr/bin/nu" >> /etc/shells
ADD config/useradd /etc/default/useradd
# Install utilities.
RUN --mount=type=cache,target=/var/cache/libdnf5 \
dnf5 -y install b3sum zoxide p7zip
#
# Add Zoxide Nushell integration.
RUN mkdir -p /usr/share/nushell/vendor/autoload/env && \
zoxide init nushell > /usr/share/nushell/vendor/autoload/zoxide.nu
# Add Terra Repository.
RUN --mount=type=cache,target=/var/cache/libdnf5 \
dnf5 -y install --nogpgcheck --repofrompath 'terra,https://repos.fyralabs.com/terra$releasever' terra-release && \
curl -fsSL https://github.com/terrapkg/subatomic-repos/raw/main/terra.repo | tee /etc/yum.repos.d/terra.repo
# Enable Free and Non-Free Repositories.
RUN --mount=type=cache,target=/var/cache/libdnf5 \
dnf5 -y install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-44.noarch.rpm && \
dnf5 -y install https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-44.noarch.rpm
# Override `KillUserProcesses` to `no`.
ADD config/override_kill_user_processes.conf /etc/systemd/logind.conf.d/override_kill_user_processes.conf
# Add network configuration.
ADD config/<redacted> /etc/NetworkManager/system-connections/<redacted>.nmconnection
RUN chmod 600 /etc/NetworkManager/system-connections/<redacted>.nmconnection
# Add Carapace
ADD config/fury.repo /etc/yum.repos.d/fury.repo
RUN --mount=type=cache,target=/var/cache/libdnf5 \
dnf5 -y install carapace
RUN carapace _carapace nushell > /usr/share/nushell/vendor/autoload/carapace.nu && \
echo '$env.CARAPACE_BRIDGES = "zsh,fish,bash,inshellisense"' \
> /usr/share/nushell/vendor/autoload/env/carapace_bridges.nu
# Install `sbctl`.
RUN --mount=type=cache,target=/var/cache/libdnf5 \
dnf5 -y copr enable chenxiaolong/sbctl && \
dnf5 -y install sbctl
# Install Tuned, Tuned-PPD
RUN --mount=type=cache,target=/var/cache/libdnf5 \
dnf5 -y install tuned tuned-ppd && \
systemctl enable tuned tuned-ppd
# Install ncurses for clear command.
RUN --mount=type=cache,target=/var/cache/libdnf5 \
dnf5 -y install ncurses
FROM fedora-iot-opinionated as ben-server
RUN rm /var/{log,cache,lib}/* -rf
RUN bootc container lint
RUN dnf5 -y upgrade
# Normalize layers with Chunkah.
FROM quay.io/coreos/chunkah:latest AS chunkah
RUN --mount=from=ben-server,src=/,target=/chunkah,ro \
--mount=type=bind,target=/run/src,rw \
chunkah build --prune /sysroot/ --max-layers 128 --label ostree.commit- --label ostree.final-diffid- > /run/src/out.ociarchive
FROM oci-archive:out.ociarchive
LABEL containers.bootc=1
LABEL ostree.bootable 1
ENV container=oci
STOPSIGNAL SIGRTMIN+3
ENV fedora_version=44
CMD ["/sbin/init"]
And my dedicated Installer image (Containerfile.installer):
FROM quay.io/fedora/fedora-bootc:44
RUN --mount=type=cache,target=/var/cache/libdnf5 \
dnf install -y \
anaconda \
anaconda-install-env-deps \
anaconda-dracut \
dracut-config-generic \
dracut-network \
net-tools \
squashfs-tools \
grub2-efi-x64-cdboot \
python3-mako \
lorax-templates-* \
biosdevname \
prefixdevname \
&& dnf clean all
RUN mkdir -p /boot/efi && cp -ra /usr/lib/efi/*/*/EFI /boot/efi
RUN mkdir /var/mnt
I build them, and then generate the ISO with:
sudo image-builder build \
--bootc-ref localhost/anaconda:44 \
--bootc-installer-payload-ref localhost/ben-server:44 \
--bootc-default-fs ext4 \
--blueprint config.toml \
bootc-installer
Here’s the command I use to build:
distrobox-host-exec sudo image-builder build --bootc-ref localhost/anaconda:44 --bootc-installer-payload-ref localhost/ben-server:44 --bootc-default-fs ext4 --blueprint config.toml bootc-installer
Yes, I am in a Distrobox, but it’s using the host’s Podman in rootful mode so it shouldn’t affect my build (I think).
And the thing is, when I use --type qcow2, it works:
Questions
- Is the
malformed pax extensionerror a known bug in F44’sostree/libarchive? - Is my usage of
chunkahin the multi-stage build incorrect, or is there another way I should force F44 Podman to write ostree-compatible layers? - Am I missing something fundamental about building F44 IoT bootc installers?
Any help or pointers would be immensely appreciated.
Thanks for reading!

