Distrobuilder for Kali Desktop (VM) in Incus (Running on Ubuntu 22.04 Host)

I’ve gone down quite a rabbithole to try and get a kali desktop vm to launch in incus.

The scenario: distrobuilder completes and creates an incus image but then that image never completely starts in incus. to get the vm built with distrobuilder, i based the chnages to the kali.yaml file on items i found in the debian.yaml file since kali is most like a standard debian machine (package names, config locations etc).

I have confirmed the following scenarios build working vms with distro builder:
kali (container)
ubuntu (vm)
debian (vm)
opensuse (vm)
kde (vm)

When it gets tyo running the kali vm ive created that seems to pass grub but then never loads and the state in incus info is as follows:

Name: kalidt4
Description:
Status: RUNNING
Type: virtual-machine
Architecture: x86_64
PID: 638165
Created: 2025/05/27 04:21 CDT
Last Used: 2025/05/27 04:21 CDT
Started: 2025/05/27 04:21 CDT

Resources:
Processes: -1
Disk usage:
root: 1.00KiB
Network usage:
eth0:
Type: broadcast
State: UP
Host interface: tap6332a52a
MAC address: 10:66:6a:68:26:f9
MTU: 1500
Bytes received: 0B
Bytes sent: 0B
Packets received: 0
Packets sent: 0
IP addresses:
inet6: fd42:d70e:72e:3b78:1266:6aff:fe68:26f9/64 (global)

Log:

architecture: x86_64
config:
image.architecture: amd64
image.description: Kali kali-rolling amd64 (desktop) (20250527_0905)
image.name: kali-kali-rolling-amd64-desktop-20250527_0905
image.os: kali
image.release: kali-rolling
image.serial: “20250527_0905”
image.variant: desktop
limits.memory: 14GiB
security.csm: “true”
security.secureboot: “false”
volatile.base_image: adf3bb12108e4c643cedc513178e294255ed6b3b314ff7b9a40bf21545cf18df
volatile.cloud-init.instance-id: 3cf034dd-2c4e-49a9-9a8d-9f3420e8777b
volatile.eth0.host_name: tap6332a52a
volatile.eth0.hwaddr: 10:66:6a:68:26:f9
volatile.last_state.power: RUNNING
volatile.uuid: 2771826d-110a-4118-9f8f-0eff612333b9
volatile.uuid.generation: 2771826d-110a-4118-9f8f-0eff612333b9
volatile.vm.definition: pc-q35-9.0
volatile.vsock_id: “2334106212”
devices: {}
ephemeral: false
profiles:

  • default
    stateful: false
    description: “”

at this point the log shows:
qemu.qmp.log
[2025-05-27T04:21:44-05:00] QUERY: {“execute”:“qom-get”,“arguments”:{“path”:“/machine”,“property”:“type”}}
[2025-05-27T04:21:44-05:00] REPLY: {“return”: “pc-q35-9.0-machine”}

[2025-05-27T04:21:44-05:00] QUERY: {“execute”:“query-cpus-fast”}
[2025-05-27T04:21:44-05:00] REPLY: {“return”: [{“thread-id”: 638169, “props”: {“core-id”: 0, “thread-id”: 0, “node-id”: 0, “socket-id”: 0}, “qom-path”: "/machine

[2025-05-27T04:21:44-05:00] QUERY: {“execute”:“netdev_add”,“arguments”:{“fds”:“/dev/net/tun.0:/dev/net/tun.1”,“id”:“incus_eth0”,“type”:“tap”,“vhost”:true,"vhostf
[2025-05-27T04:21:44-05:00] REPLY: {“return”: {}}

[2025-05-27T04:21:44-05:00] QUERY: {“execute”:“device_add”,“arguments”:{“addr”:“00.0”,“bootindex”:1,“bus”:“qemu_pcie4”,“driver”:“virtio-net-pci”,“id”:"dev-incus_
[2025-05-27T04:21:44-05:00] REPLY: {“return”: {}}

[2025-05-27T04:21:44-05:00] QUERY: {“execute”:“blockdev-add”,“arguments”:{“aio”:“native”,“cache”:{“direct”:true,“no-flush”:false},“discard”:“unmap”,“driver”:"hos
[2025-05-27T04:21:44-05:00] REPLY: {“return”: {}}

[2025-05-27T04:21:44-05:00] QUERY: {“execute”:“device_add”,“arguments”:{“bootindex”:0,“bus”:“qemu_scsi.0”,“channel”:0,“device_id”:“incus_root”,“drive”:"incus_roo
[2025-05-27T04:21:44-05:00] REPLY: {“return”: {}}

[2025-05-27T04:21:44-05:00] QUERY: {“execute”:“system_reset”}
[2025-05-27T04:21:44-05:00] REPLY: {“return”: {}}

[2025-05-27T04:21:44-05:00] QUERY: {“execute”:“set-action”,“arguments”:{“panic”:“pause”,“reboot”:“shutdown”,“shutdown”:“poweroff”}}
[2025-05-27T04:21:44-05:00] REPLY: {“return”: {}}

[2025-05-27T04:21:44-05:00] QUERY: {“execute”:“cont”}
[2025-05-27T04:21:44-05:00] REPLY: {“return”: {}}

If i force stop the vm i get the following console log as well:

SeaBIOS (version rel-1.16.3-0-ga6ed6b7)
Machine UUID 2771826d-110a-4118-9f8f-0eff612333b9
iPXE (http://ipxe.org) 05:00.0 CA00 PCI2.10 PnP PMM+7EFD3050+7EF33050 CA00
Booting from Hard Disk…

i cant seem to get the vm to load for kali at all. im wondering if there is a missing package of some sort on the host? Also is there any way to see more granular verbose debugging of what happens when the vm is starting so i can see where/why its failing? Kali Desktop is the requirement for this project, and it feels like im so close yet somehow still very far off.

heres the yaml file:

image:
  distribution: "kali"
  release: kali-rolling
  architecture: amd64
  variant: desktop


source:
  downloader: debootstrap
  url: https://kali.download/kali/
  same_as: sid
  keys:
  - |-
    -----BEGIN PGP PUBLIC KEY BLOCK-----

    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
    5L4BmZ/oTEg=
    =EJtZ
    -----END PGP PUBLIC KEY BLOCK-----
  variant: minbase

targets:
  lxc:
    create_message: |-
      You just created a {{ image.description }} container.

      To enable SSH, run: apt install openssh-server
      No default root or user password are set by LXC.

    config:
    - type: all
      before: 5
      content: |-
        lxc.include = LXC_TEMPLATE_CONFIG/debian.common.conf

    - type: all
      after: 4
      content: |-
        lxc.include = LXC_TEMPLATE_CONFIG/common.conf

    - type: user
      after: 4
      content: |-
        lxc.include = LXC_TEMPLATE_CONFIG/userns.conf

    - type: all
      content: |-
        lxc.arch = {{ image.architecture_personality }}

files:
- path: /etc/hostname
  generator: hostname

- path: /etc/hosts
  generator: hosts

- path: /etc/resolvconf/resolv.conf.d/original
  generator: remove

- path: /etc/resolvconf/resolv.conf.d/tail
  generator: remove

- path: /etc/machine-id
  generator: dump
  content: uninitialized

- path: /var/lib/dbus/machine-id
  generator: remove

- path: /etc/network/interfaces
  generator: dump
  content: |-
    # This file describes the network interfaces available on your system
    # and how to activate them. For more information, see interfaces(5).

    # The loopback network interface
    auto lo
    iface lo inet loopback

    auto eth0
    iface eth0 inet dhcp

    auto enp5s0
    iface enp5s0 inet dhcp

    source /etc/network/interfaces.d/*.cfg
  variants:
  - default

- path: /etc/systemd/network/enp5s0.network
  generator: dump
  content: |-
    [Match]
    Name=enp5s0

    [Network]
    DHCP=true

    [DHCPv4]
    UseDomains=true

    [DHCP]
    ClientIdentifier=mac
  types:
  - vm
  variants:
  - default

- name: meta-data
  generator: cloud-init
  variants:
  - cloud

- name: network-config
  generator: cloud-init
  variants:
  - cloud

- name: user-data
  generator: cloud-init
  variants:
  - cloud

- name: vendor-data
  generator: cloud-init
  variants:
  - cloud

- name: ext4
  generator: fstab
  types:
  - vm

- name: incus-agent
  generator: incus-agent
  types:
  - vm

- path: /etc/default/grub.d/50-incus.cfg
  generator: dump
  content: |-
    GRUB_RECORDFAIL_TIMEOUT=0
    GRUB_TIMEOUT=0
    GRUB_CMDLINE_LINUX_DEFAULT="${GRUB_CMDLINE_LINUX_DEFAULT} console=tty1 console=ttyS0 quiet splash nomodeset"
    GRUB_TERMINAL=console
  types:
  - vm

- path: /etc/sudoers.d/90-incus
  generator: dump
  mode: 0440
  content: |-
    # User rules for kali
    kali ALL=(ALL) NOPASSWD:ALL
  variants:
    - default


packages:
  manager: apt
  update: true
  cleanup: true
  sets:
  - packages:
    - kali-archive-keyring
    action: install
    early: true

  - packages:
    - dialog
    - init
    - iproute2
    - iputils-ping
    - isc-dhcp-client
    - locales
    - netbase
    - net-tools
    - openssh-client
    - procps
    - nano
    - vim
    - sudo
    - systemd
    action: install

    # Desktop env
  - packages:
    - kali-desktop-core
    - kali-desktop-xfce
    - x11vnc 
    action: install
    variants:
    - desktop
    types:
    - vm
# When prompted, choose lightdm as the default display manager. 
# Run sudo update-alternatives --config x-session-manager 

  - packages:
    - cloud-init
    - systemd-resolved
    action: install
    variants:
    - cloud

  - packages:
    - ifupdown
    - isc-dhcp-client
    action: install
    variants:
    - default

  - packages:
    - polkitd    
    - pkexec
    action: install
    architectures:
    - amd64
    - arm64

  - packages:
    - grub-efi
    - linux-image-amd64

    action: install
    types:
    - vm
    architectures:
    - amd64

  - packages:
    - cloud-guest-utils
    action: install
    types:
    - vm

  - packages:
    - shim-signed
    action: install
    types:
    - vm

  repositories:
  - name: sources.list
    url: |-
      deb http://kali.download/kali {{ image.release }} main contrib non-free non-free-firmware

actions:
- trigger: post-update
  action: |-
    #!/bin/sh
    set -eux

    # Create the kali user account
    getent group sudo >/dev/null 2>&1 || groupadd --system sudo
    useradd --create-home -s /bin/bash -G sudo -U kali
  variants:
  - default

- trigger: post-packages
  action: |-
    #!/bin/sh
    set -eux

    # Enable systemd-networkd
    systemctl enable systemd-networkd

    # Disable UA attach
    systemctl mask ua-auto-attach
    
- trigger: post-packages
  action: |-
    #!/bin/sh
    set -eux

    # Make sure the locale is built and functional
    echo en_US.UTF-8 UTF-8 >> /etc/locale.gen
    locale-gen en_US.UTF-8 UTF-8
    update-locale LANG=en_US.UTF-8

    # Cleanup underlying /run
    mount -o bind / /mnt
    rm -rf /mnt/run/*
    umount /mnt

    # Cleanup temporary shadow paths
    rm /etc/*-

- trigger: post-packages
  action: |-
    #!/bin/sh
    set -eux

    # Enable cloud-init units
    systemctl enable cloud-init-main.service cloud-init-local.service
  variants:
  - cloud

- trigger: post-files
  action: |-
    #!/bin/sh
    set -eux

    TARGET="x86_64"
    [ "$(uname -m)" = "aarch64" ] && TARGET="arm64"


    update-grub

    # This will create EFI/BOOT
    grub-install --uefi-secure-boot --target="${TARGET}-efi" --no-nvram --removable

    # This will create EFI/ubuntu
    grub-install --uefi-secure-boot --target="${TARGET}-efi" --no-nvram

    update-grub
    sed -i "s#root=[^ ]*#root=${DISTROBUILDER_ROOT_UUID}#g" /etc/default/grub

  types:
  - vm
- trigger: post-files
  action: |-
    #!/bin/sh
    set -eux

    # Automatic disk resize
    cat << EOF > /etc/systemd/system/incus-growpart.service
    [Unit]
    Description=Incus - grow root partition

    [Service]
    Type=oneshot
    ExecStartPre=-/usr/bin/growpart /dev/sda 2
    ExecStart=/sbin/resize2fs /dev/sda2

    [Install]
    WantedBy=default.target
    EOF

    systemctl enable incus-growpart
  types:
  - vm
  variants:
  - default
  - desktop

- trigger: post-packages
  action: |-
    #!/bin/sh
    set -eux

    # Disable location service
    systemctl mask geoclue.service

    # Timezone
    rm -f /etc/localtime
    ln -s /usr/share/zoneinfo/UTC /etc/localtime
    echo UTC > /etc/timezone

    # Locale
    echo en_US.UTF-8 UTF-8 > /etc/locale.gen
    locale-gen
    echo LANG=en_US.UTF-8 > /etc/locale.conf

    # User
    USERNAME="kali"
    getent group sudo >/dev/null 2>&1 || groupadd --system sudo
    useradd --create-home -s /bin/bash -G sudo,video,users -U ${USERNAME}

    echo "/usr/sbin/lightdm" > /etc/X11/default-display-manager
    DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true dpkg-reconfigure lightdm
    echo set shared/default-x-display-manager lightdm | debconf-communicate

    cat << EOF > /etc/lightdm/lightdm.conf.d/12-autologin.conf
    [SeatDefaults]
    autologin-user=${USERNAME}
    EOF

    systemctl enable lightdm.service

    # SCREENLOCK SETTINGS
    # edit ~/.config/xfce-power-manager/config
    #[Session]
    # Screen lock
    # LockScreenDelay = 60000  # 1 minute in milliseconds
    #LockScreenDelay = 3600000  # One hour in milliseconds (or remove the line)

    # Screen Saver
    # ScreenSaver = 1 # Enable screen saver (or set to 0 to disable)
    #ScreenSaver = 0
    
    cat << EOF > /home/kali/firstboot.sh
    #!/bin/sh

    set -e

    # Delete this script
    rm /home/ubuntu/firstboot.sh
    EOF

    chown kali:kali /home/kali/firstboot.sh
    chmod +x /home/kali/firstboot.sh

    cat << EOF > /etc/systemd/user/firstboot.service
    [Unit]
    Description=One time boot script
    After=dbus.service
    After=display-manager.service
    ConditionPathExists=/home/kali/firstboot.sh

    [Service]
    Type=oneshot
    ExecStart=/home/kali/firstboot.sh

    [Install]
    WantedBy=default.target
    EOF

    mkdir -p /home/kali/.config/systemd/user/default.target.wants
    ln -s /etc/systemd/user/firstboot.service /home/kali/.config/systemd/user/default.target.wants/firstboot.service

    chown -R kali:kali /home/kali/.config
  variants:
  - desktop
  types:
  - vm

mappings:
  architecture_map: debian

Thanks for doing this!

Could you please apply code formatting to the command output and the developing distrobuilder configuration for Kali? See more here (or ask me if something is not clear in that post). Without the appropriate format it is not possible to grab the work-in-progress configuration.

This is an example of code formatting.

i added the code formatting block. I am still tryong to get to the bottom of why this kali vm of all vms ive tried wont launch. please help. thnak you!

There’s the Ubuntu desktop VM image, images:plucky/desktop. Have you managed to recreate it with distrobuilder, then launch to verify that it works?

I built the plucky vm image with distrobuilder and it is failing in the same way (never boots) as the kali vm.
Is this an issue of incus not being able to launch newer kerneled vms? (my host system is ubuntu 22) or is this a matter of missing packages at the host level to support incus running newer kernels, and if so what are they?

It’s difficult to say, in fact we cannot say much if we do not have a common dev environment.
Can you try using distrobuilder in a VM (let’s say Ubuntu 24.04 LTS), generate the Ubuntu VM image, and start it on the host? By doing so, it would be easy to replicate and figure out whether some system-specific configuration is messing everything up, or whether it’s indeed a bug.

Here is me recreating the VM image images:ubuntu/plucky/desktop.

First, I create a VM with Ubuntu 24.04 LTS, resize it up a bit to 15GiB because images require more space than the default 10GiB.

$ incus init --vm images:ubuntu/24.04/cloud distrobuilder
Creating distrobuilder
$ incus config device override distrobuilder root size=15GiB
Device root overridden for distrobuilder
$ incus start distrobuilder
$ incus exec distrobuilder -- su -l ubuntu
Error: VM agent isn't currently running
$ incus exec distrobuilder -- su -l ubuntu
Error: VM agent isn't currently running
$ incus exec distrobuilder -- su -l ubuntu
su: user ubuntu does not exist or the user entry does not contain all the required fields
$ incus exec distrobuilder -- su -l ubuntu
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

ubuntu@distrobuilder:~$

Then, follow the instructions from GitHub - lxc/distrobuilder: System container image builder for LXC and Incus to install distrobuilder from source and set up other packages. The following you can copy-paste in the VM and it will generate the VM Desktop image for you.

sudo apt update
sudo apt install -y golang-go gcc debootstrap rsync gpg squashfs-tools git make build-essential libwin-hivex-perl wimtools genisoimage
mkdir -p $HOME/go/src/github.com/lxc/
cd $HOME/go/src/github.com/lxc/
git clone https://github.com/lxc/distrobuilder
cd ./distrobuilder
make
cd
sudo apt install -y btrfs-progs dosfstools qemu-kvm
wget https://github.com/lxc/lxc-ci/raw/refs/heads/main/images/ubuntu.yaml
sudo $HOME/go/bin/distrobuilder build-incus --vm ubuntu.yaml rootfs -o image.architecture=amd64 -o image.release=plucky -o image.variant=desktop

Let’s check the generated image.

ubuntu@distrobuilder:~$ ls -l 
total 36
drwxrwxr-x 5 ubuntu ubuntu  4096 May 28 21:56 go
drwxr-xr-x 2 root   root    4096 May 28 22:12 rootfs
-rw-rw-r-- 1 ubuntu ubuntu 27080 May 28 21:57 ubuntu.yaml
ubuntu@distrobuilder:~$ ls -l rootfs/
total 1327552
-rw-r--r-- 1 root root 1359404032 May 28 22:11 disk.qcow2
-rw-r--r-- 1 root root        724 May 28 22:12 incus.tar.xz
ubuntu@distrobuilder:~$ 

Looks good. Now we get it out of the VM and onto the host. We need to put the generated VM image on the host in order to launch it.

$ incus file pull -r distrobuilder/home/ubuntu/rootfs/ .
$ cd rootfs/
$ ls
disk.qcow2  incus.tar.xz
$ incus image import  incus.tar.xz disk.qcow2 --alias mypluckyimage
Image imported with fingerprint: f9d85959d9b28cb37f4490a4aed5b0d061b188a258ed1d46d0791119af73839a
$ incus image list mypluckyimage 
+---------------+--------------+--------+------------------------------------------------+--------------+-----------------+------------+-----------------------+
|     ALIAS     | FINGERPRINT  | PUBLIC |                  DESCRIPTION                   | ARCHITECTURE |      TYPE       |    SIZE    |      UPLOAD DATE      |
+---------------+--------------+--------+------------------------------------------------+--------------+-----------------+------------+-----------------------+
| mypluckyimage | f9d85959d9b2 | no     | Ubuntu plucky amd64 (desktop) (20250526_16:05) | x86_64       | VIRTUAL-MACHINE | 1296.43MiB | 2025/05/29 01:29 EEST |
+---------------+--------------+--------+------------------------------------------------+--------------+-----------------+------------+-----------------------+
$ incus launch --vm mypluckyimage myplucky --console=vga -c security.secureboot=false -c limits.memory=3GiB
Launching myplucky
...

Were defintly building from a slightly different process. i spont the betetr half of a day getting an ubuntu 24.04 vm setup (Its the Host machine itself not running in incus)

on which i am installing distrobuider as such:
distrobuilder from the snap package (3.2)
from apt: btrfs-progs,dosfstools,qemu-kvm
then grabbing the ubuntu.yaml from the repo
i then modify the ubuntu.yaml to incde the following:
image:
distribution: “ubuntu”
release: plucky
architecture: amd64
variant: desktop
then running the following:
distrobuilder --debug build-incus ubuntu.yaml --vm --import-into-incus=ubvmplucky
i notice you have a few different command lines options im wondering if they are making the difference & what specifically are they adding in this case:
–cache-dir /root/build/cache/ rootfs -o image.serial=20250526_16:05

also note here are all the incus debs and additional tools ive added:
incus, qemu-system, incus-tools, incus-extra, p7zip-full, zfs-dkms, zfsutils-linux

and the kvm tools for migrating from images:
qemu-kvm,virt-manager,libvirt-daemon-system,virtinst,libvirt-clients,bridge-utils,guestfs-tools

as it stands when i build the plucky vm deom distrobuilder it fails, but when i install it from the image library it launches.

So major questions:

  • is distrobuilder from snap going to work or MUST i install from source (and what version gets created by the souce install)?
  • whats is the effect of adding the command line options:
    rootfs & -o image.serial=20250526_16:05. to the build comamnd line?
  • what is the effect of adding the --cache-dir (it will just use /tmp/cache if not added if im not mistaken)
  • what about -o source.url=http://archive.ubuntu.com/ubuntu isnt that handled by the sources.list in the yaml file already?

so just a quick update still theres something missing from getting from distrobuilder to incus:

when i run the plucky vm image from the lincus container repo it works, but when i run the image imported from local (built with distrobuilder) no dice. i went ahead and changed my distribuilder command line to be:

distrobuilder --cache-dir /opt/distrocache build-incus --vm ubuntu.yaml rootfs -o image.serial=20250526_16:05 --import-into-incus=ubvmplucky

same problem as before. image doesnt start, and never gets an ipv4 ip

i then went back and built distrobuilder from source, rebuilt again with that (version shows same version as the snap but for sake of trying used the $HOME/go/bin/distrobuilder anyway)

only difference at this point was using alternate repo because arcive.ubuntu.com is running dog slow so used a fast mirror in america instead. (editied ubuntu.yaml source and sources.list)
note: when i treid only passing in source from command line as shown i would get an error mid build about fuse3 not being available. so using the source and source.lsit in the yaml file worked better.

heres whats come of the 3 attemps:
pluckyvm is from the image repo
plucky-dist is build with snap vefsion of distrobuilder (3.2)
plucky-dist2 is built from the src compiled version of distrobuilder (alse 3.2)

±--------------±--------±----------------------±-------------------------------------------------±----------------±----------+
| plucky-dist | RUNNING | | fd42:ee19:d60f:c59e:1266:6aff:fe85:2676 (eth0) | VIRTUAL-MACHINE | 0 |
±--------------±--------±----------------------±-------------------------------------------------±----------------±----------+
| plucky-dist-2 | RUNNING | | fd42:ee19:d60f:c59e:1266:6aff:fe05:bd5 (eth0) | VIRTUAL-MACHINE | 0 |
±--------------±--------±----------------------±-------------------------------------------------±----------------±----------+
| pluckyvm | RUNNING | 10.0.100.200 (enp5s0) | fd42:ee19:d60f:c59e:a2ae:836e:3246:5942 (enp5s0) | VIRTUAL-MACHINE | 0 |
| | | | fd42:ee19:d60f:c59e:1266:6aff:fe22:bd38 (enp5s0) | | |
±--------------±--------±----------------------±-------------------------------------------------±----------------±----------+

im at a total loss at this point for why it works from the image but not from distrobuilder, no errors occur during distrobuilders run…

Name: pluckyvm
Description: 
Status: RUNNING
Type: virtual-machine
Architecture: x86_64
PID: 1841
Created: 2025/05/29 10:21 CDT
Last Used: 2025/05/29 13:25 CDT
Started: 2025/05/29 13:25 CDT

Operating System:
  OS: Ubuntu
  OS Version: 25.04
  Kernel Version: 6.14.0-15-generic
  Hostname: pluckyvm
  FQDN: localhost

Resources:
  Processes: 106
  Disk usage:
    root: 104.18MiB
  CPU usage:
    CPU usage (in seconds): 100
  Memory usage:
    Memory (current): 1.66GiB
  Network usage:
    enp5s0:
      Type: broadcast
      State: UP
      Host interface: tap21154a71
      MAC address: 10:66:6a:22:bd:38
      MTU: 1500
      Bytes received: 75.85kB
      Bytes sent: 81.45kB
      Packets received: 516
      Packets sent: 869
      IP addresses:
        inet:  10.0.100.200/24 (global)
        inet6: fd42:ee19:d60f:c59e:a2ae:836e:3246:5942/64 (global)
        inet6: fd42:ee19:d60f:c59e:1266:6aff:fe22:bd38/64 (global)
        inet6: fe80::1266:6aff:fe22:bd38/64 (link)
    lo:
      Type: loopback
      State: UP
      MTU: 65536
      Bytes received: 27.45kB
      Bytes sent: 27.45kB
      Packets received: 329
      Packets sent: 329
      IP addresses:
        inet:  127.0.0.1/8 (local)
        inet6: ::1/128 (local)

Name: plucky-dist-2
Description:
Status: RUNNING
Type: virtual-machine
Architecture: x86_64
PID: 45357
Created: 2025/05/29 13:49 CDT
Last Used: 2025/05/29 13:50 CDT
Started: 2025/05/29 13:50 CDT

Resources:
Processes: -1
Disk usage:
root: 1.00KiB
Network usage:
eth0:
Type: broadcast
State: UP
Host interface: tap31d5ef4c
MAC address: 10:66:6a:05:0b:d5
MTU: 1500
Bytes received: 142B
Bytes sent: 0B
Packets received: 1
Packets sent: 0
IP addresses:
inet6: fd42:ee19:d60f:c59e:1266:6aff:fe05:bd5/64 (global)

so yeah thats where things are. very very confusing as to why it dosent build a bootable image at all when using distrobuilder (for me)

Distrobuilder from snap package should work just fine. Compiling from source is quite straightforward and I decided to do it that way. Also, if there is some opportunity to test a new feature, it’s easy to do so.

The rootfs is the name of the directory to put the generated image. I copied that from the build logs at https://images.linuxcontainers.org/ The name could be anything.
Same with --cache-dir. I copied it from the lxc-ci build logs, along with the source.url part. Therefore, it should not make a difference in the result.
I simplified the line and now it is:

sudo $HOME/go/bin/distrobuilder build-incus --vm ubuntu.yaml rootfs -o image.architecture=amd64 -o image.release=plucky -o image.variant=desktop

Your build environment could make a difference. By running distrobuilder in a controlled environment, it makes it easy to figure out if some remnants from the host are causing trouble.

In your case I would build the image in a VM, an Incus VM of Ubuntu 24.04 LTS. You just drag and drop the necessary commands shown above and let it build. It took me about 12 minutes to generate the image inside rootfs/.

I also tried with an initial Kali VM image. I did not manage to generate a proper desktop image. The file was only about 330MB, hence there was no graphical interface.
However, when I tried to boot it, it booted successfully.
When you say that it did not work for you, can you qualify what exactly do you get?
Because if the issue that you are facing is that the Kali VM does not even boot, then you need to get a Kali image that at least boots (even without the graphical interface).