Menu
About Services Journey Work With Me
Person troubleshooting on a laptop in a dark workspace
Technology Mar 12, 2026 • 22 min read

The Installer Tried to Destroy My Storage Design. AI Found a Better Path.

The Kali installer tried to flatten my encrypted LVM into a single ext4 partition. AI caught it and guided the pivot to debootstrap, then later diagnosed the boot failure that everyone misblames on GPU drivers.

Share:
Lee Foropoulos

Lee Foropoulos

22 min read

Prompt Your Way to Linux: A 4-Part Series

Part 1: Picking Your DistroPart 2: Storage and EncryptionPart 3: Manual InstallPart 4: Services and GPU

Picture this: you've just spent two hours building a carefully designed encrypted LVM layout. Six logical volumes, three encrypted disks, everything exactly where it needs to be. Then the Kali installer tries to flatten the whole thing into a single ext4 partition.

The graphical installer already crashed from the hybrid GPU. Now the text installer is actively trying to undo your work. You could fight it for another three hours. Or you could describe the problem to AI and discover something you probably haven't considered: skip the installer entirely and build the OS by hand with debootstrap. That pivot will save the entire build.

The Installer Was Supposed to Just Work

After spending hours in Part 2 crafting an encrypted LVM storage layout with separate volumes for root, swap, docker, ollama, postgres, and home, the next step seems almost boring. Launch the Kali installer, choose manual partitioning, assign mount points, click next a few times, done. Twenty minutes, tops.

That expectation is completely wrong.

The graphical installer will crash immediately on hybrid GPU hardware. Intel integrated graphics alongside an NVIDIA discrete GPU? The GUI installer can't handle the hybrid framebuffer. Black screens. X server failures. Total dead end. Not a single menu renders before the whole thing locks up.

Fine. The text installer it is.

The text-based installer avoids the GPU crash, and for a moment things look promising. It boots, detects the NVMe drive, offers a manual partitioning option. But then it introduces a problem far worse than a crashed GUI.

Terminal session showing system diagnostics on a dark screen
When the graphical installer fails, the terminal becomes your only friend. Get comfortable here.

The Moment You Need to Stop

Here's what happens inside the text installer's manual partitioning screen: it detects nvme0n1p3_crypt (the opened LUKS container) and keeps trying to format it as plain ext4.

That's not what it is. That mapped device is supposed to be an LVM physical volume sitting inside the encrypted container. On top of that PV sits a volume group, and on top of that VG sit six logical volumes: root, swap, docker, ollama, postgres, and home. If the installer writes an ext4 filesystem directly onto nvme0n1p3_crypt, it will obliterate the entire multi-volume design in about three seconds.

Describe this to AI. The response will be immediate and specific:

"Stop. Don't proceed. The installer is misinterpreting your storage stack. It's treating your LUKS container as a raw partition instead of recognizing the LVM layer inside it. If you let it format, you'll lose every logical volume."

The strange part? Drop to a shell from the installer and run lvs. Every logical volume shows up perfectly. The live environment understands the storage layout. The installer's partitioning tool does not. It sometimes shows the LUKS container, sometimes shows the volume group, but rarely displays the actual logical volumes where mount points need to go.

The pattern is unmistakable once you know what to look for: the live shell sees everything correctly; the installer sees wrong things. That makes the installer untrustworthy for this build.

If the installer tries to flatten your encrypted container into a single filesystem, stop immediately. It's about to destroy your design.

This is where the whole approach pivots. Stop asking "how do we make the installer work" and start asking "how do we install Kali without the installer?"

The Manual Install Path: debootstrap

The answer is clean: mount the target filesystems yourself, use debootstrap to pull down a base system, chroot into it, and build the OS by hand.

This isn't a downgrade or a desperate workaround. For a complex, multi-volume encrypted build like this one, it's actually the professional approach. Here's why it beats wrestling with the installer:

  • Preserves the storage design exactly as built. No installer reinterpreting your layout.
  • Avoids GUI instability on hybrid GPU hardware entirely.
  • Gives complete control over package selection and configuration.
  • More predictable than retrying the installer and hoping it reads LVM correctly this time.

Walking Through It, Step by Step

This is the part where the process gets genuinely satisfying. Each step is a prompt, a response, and then execution. Here's the full sequence.

Step 1: Mount the target filesystem tree

Start with the root logical volume, then layer everything else on top. The order matters:

bash
1mount /dev/mapper/vg0-root /mnt
2mkdir -p /mnt/boot /mnt/boot/efi /mnt/home
3mkdir -p /mnt/var/lib/docker /mnt/var/lib/ollama /mnt/var/lib/postgresql
4mount /dev/nvme0n1p2 /mnt/boot
5mount /dev/nvme0n1p1 /mnt/boot/efi
6mount /dev/mapper/vg0-home /mnt/home
7mount /dev/mapper/vg0-docker /mnt/var/lib/docker
8mount /dev/mapper/vg0-ollama /mnt/var/lib/ollama
9mount /dev/mapper/vg0-postgres /mnt/var/lib/postgresql

Why mount everything first? When debootstrap writes files, they land on the correct target volumes from the start. If you only mount root and bootstrap, then mount /home later, you'll have bootstrap artifacts sitting on the root volume where /home should be.

Step 2: Bootstrap the base system

bash
debootstrap --arch=amd64 kali-rolling /mnt http://http.kali.org/kali

Before entering the chroot, bind-mount the host's pseudo-filesystems so the chroot environment can interact with hardware and the network:

bash
1mount --bind /dev /mnt/dev
2mount --bind /dev/pts /mnt/dev/pts
3mount --bind /proc /mnt/proc
4mount --bind /sys /mnt/sys
5mount --bind /sys/firmware/efi/efivars /mnt/sys/firmware/efi/efivars
6cp /etc/resolv.conf /mnt/etc/resolv.conf
7chroot /mnt /bin/bash

Each of those bind mounts serves a specific purpose: /dev and /dev/pts let package scripts access devices and terminals. /proc and /sys are needed for initramfs generation and kernel module detection. The EFI vars mount is critical for GRUB EFI installation. And copying resolv.conf gives the chroot DNS resolution so apt can actually reach repositories.

Step 3: Configure everything inside the chroot

Here's the full configuration checklist, and each one matters:

  1. Apt sources pointing to kali-rolling main contrib non-free non-free-firmware
  2. Core packages: linux-image-amd64, systemd, cryptsetup-initramfs, lvm2, grub-efi-amd64
  3. Desktop environment: xorg, xfce4, lightdm, kali-desktop-xfce
  4. System configuration: hostname, locale (en_US.UTF-8), timezone
  5. User creation: adduser, adding to sudo group
  6. Crypttab and fstab: referencing the correct UUIDs for each layer
  7. Initramfs rebuild: update-initramfs -u -k all to include LUKS and LVM hooks
  8. GRUB install: grub-install --target=x86_64-efi --efi-directory=/boot/efi followed by update-grub

The whole process takes about 45 minutes. Not because it's difficult, but because each step needs deliberate attention. Feed each step to AI, get the commands, understand the reasoning, and watch for pitfalls before they happen.

Person working on a laptop with code visible on screen
Building an OS by hand sounds intimidating. With AI providing each command and explaining the reasoning, it's methodical rather than mysterious.

First Boot and the Sudo Surprise

After debootstrap, chroot configuration, initramfs generation, and GRUB installation, it's the moment of truth. Unmount everything in reverse order, pull out the USB, reboot.

The first boot works. The LUKS passphrase prompt appears exactly as expected. Enter the passphrase, GRUB loads, Kali boots, LightDM displays the login screen, XFCE renders. Everything that failed with the graphical installer is now running perfectly from a hand-built system.

But then comes a small, annoying surprise. Your user account can't run sudo. Every command returns:

user is not in the sudoers file. This incident will be reported.

You definitely added the user to the sudo group during the chroot setup. You can verify it with groups and see sudo listed. So what's going on?

Here's what's actually happening: the current login session hasn't picked up the group change. Group membership is evaluated at login time. Since the user was created and added to sudo inside the chroot but never actually logged in through a proper session manager, the running session doesn't reflect the membership. The fix? Log out and log back in. That's it.

This is one of those classic Linux gotchas that trips up beginners and experienced users alike. You know you added the group. You can prove you added the group. But the system doesn't care what's in /etc/group until the next login evaluates it. Without AI pointing this out immediately, you could easily burn an hour going down a rabbit hole of PAM configurations and sudoers file edits for nothing.

The Emergency Mode Incident

Buckle up. This is the single most valuable debugging lesson from the entire four-part build, and it reads like a whodunit where every clue points at the wrong suspect.

After the successful first boot and some additional configuration work (including installing NVIDIA proprietary drivers for the discrete GPU), you reboot. Instead of the login screen, you get dumped into emergency mode. Red text. Failed units. A root shell prompt asking you to figure out what went wrong.

The obvious conclusion hits immediately: "NVIDIA broke my system." You just installed GPU drivers. The system was working before. Now it isn't. Cause and effect, right?

Wrong. Completely, spectacularly wrong.

Follow the Evidence, Not the Story

Paste the journalctl output and the list of failed systemctl units into AI. The prompt is straightforward: "System dropped to emergency mode after NVIDIA driver work. Here are the journal logs. What went wrong?"

Watch what happens next. AI ignores the NVIDIA narrative entirely and goes straight to the evidence. The actual errors in the journal are:

EXT4-fs (sda1): Can't find ext4 filesystem
EXT4-fs (sdb1): Can't find ext4 filesystem

Those aren't GPU errors. Those are storage mount failures. The system is trying to mount /dev/sda1 and /dev/sdb1 as ext4 filesystems. But sda1 and sdb1 are LUKS encrypted containers. They don't contain ext4 filesystems directly. They contain encrypted data that, when opened through cryptsetup, exposes mapper devices that contain ext4 filesystems.

The real culprit is /etc/fstab. The fstab entries for the two external data disks reference the raw partition UUIDs with ext4 as the filesystem type. The system tries to mount encrypted blocks as if they were plain filesystems, fails (obviously), and because they're listed without nofail, systemd treats the failures as fatal and drops to emergency mode.

NVIDIA never had anything to do with it. The timing was a coincidence. The fstab was wrong the entire time; it just took a reboot to expose it.

The Correct Pattern for Encrypted Data Mounts

In /etc/crypttab: reference the raw LUKS partition UUIDs (the physical partitions like sda1, sdb1). This tells the system to open the encrypted containers at boot.

In /etc/fstab: reference the ext4 UUIDs from the opened mapper devices (/dev/mapper/cryptarchive, /dev/mapper/cryptanalysis). These are the actual filesystems you want to mount.

Always add nofail to optional data mounts. If something goes wrong with a secondary disk, your system still boots instead of dropping to emergency mode.

Never put raw encrypted partition UUIDs in fstab with ext4 as the type. The correct chain is: /dev/sda1 → LUKS open → /dev/mapper/cryptarchive → ext4 mount → /srv/archive.

The Fix

Once the real problem is visible, the solution is straightforward:

  1. Update /etc/crypttab with the correct LUKS partition UUIDs for both external disks
  2. Update /etc/fstab to reference the mapper device UUIDs (not the raw partition UUIDs) with nofail flags
  3. Rebuild initramfs to pick up the crypttab changes
  4. Reboot

System comes up clean. NVIDIA drivers work fine. They were never the problem.

Diagnose by Evidence, Not by Timing

This is the lesson worth tattooing on your brain. Not just for this build, but for every Linux problem you'll ever face.

Just because something fails after you install a driver doesn't mean the driver caused it.

The timeline tells a convincing story: install NVIDIA drivers, reboot, emergency mode. Any reasonable person would blame the GPU drivers. The internet is full of forum posts from people who blamed the GPU drivers for exactly this kind of boot failure. And most of them probably reformatted and reinstalled when the real fix was a two-line edit in fstab.

The better approach? Read the logs. Trust the logs. Ignore the narrative.

"Correlation isn't causation, and timing isn't evidence. The journal tells you what failed. Start there, not with what you changed last."

This debugging discipline works everywhere:

  • System won't boot? Check journalctl -xb for the actual failed units. Don't guess based on what you installed yesterday.
  • Service won't start? Read the service's own logs before assuming a dependency broke it.
  • Network is down? Check ip addr and systemctl status NetworkManager before blaming the firewall change you made.

Feed your logs to AI. Let it read the evidence without your narrative coloring the analysis. You'll be shocked how often the real problem has nothing to do with the thing you just changed.

The Analysis Disk Mystery

One more curveball. After fixing the archive disk mount, you try to open the analysis disk (sdb1) with cryptsetup luksOpen. The passphrase gets rejected.

This is confusing. Both external disks were set up during the Part 2 storage work. The archive disk opens fine with its passphrase. The analysis disk refuses.

Work through the possibilities methodically:

  • Wrong passphrase? Possible. During a long install session with multiple LUKS containers, it's easy to mix up which passphrase goes with which disk.
  • Keyboard layout mismatch? If the passphrase was set during a live USB session with a different keyboard layout than the installed system, special characters might map differently.
  • Creation-time input error? When you type a passphrase blindly (no echo) during luksFormat, a typo becomes permanent. You confirmed it once, also blindly, and moved on.

The most likely explanation is the simplest: during the initial setup, with multiple disks being encrypted in sequence, the passphrase for the analysis disk was either mistyped or confused with another one.

Here's the practical takeaway: during initial install, use simple temporary passphrases for your LUKS containers and rotate them to strong passphrases after the system is stable. That way you're not debugging passphrase mysteries at 2 AM while also trying to get your system to boot. Label your disks clearly in a physical notebook too, not just in your head.

Use simple temporary passphrases during install and rotate them later. Debugging a typo in a blind passphrase entry at 2 AM is nobody's idea of productivity.

You Just Built an OS by Hand

Take a second to appreciate what just happened here. The installer tried to destroy your storage design. You sidestepped it entirely, built the OS from raw packages with debootstrap, and ended up with a cleaner, more controlled system than any installer would have produced.

Emergency mode tried to convince you NVIDIA was the villain. You read the logs, found the real culprit hiding in fstab, and fixed it in two lines. That's the kind of debugging instinct that separates people who use Linux from people who actually understand it.

The hard infrastructure work is done. The encrypted storage is solid, the base system is running, and every boot-time failure has been tracked down and eliminated.

In Part 4, things get fun. Docker containers, the Ollama AI runtime, PostgreSQL, and yes, finally getting NVIDIA CUDA working properly so this machine can run local AI models. You've built the foundation. Now it's time to put it to work.

Part 3 Checkpoints 0/9
How was this article?

Share

Link copied to clipboard!

You Might Also Like

Lee Foropoulos

Lee Foropoulos

Business Development Lead at Lookatmedia, fractional executive, and founder of gotHABITS.

🔔

Never Miss a Post

Get notified when new articles are published. No email required.

You will see a banner on the site when a new post is published, plus a browser notification if you allow it.

Browser notifications only. No spam, no email.