The TrueNAS installer doesn’t have a way to use anything less than the full device. This is a waste of capacity when installing to large NVMe which is usually several hundred of GB or even TB. TrueNAS SCALE will use only a few GB for its system files so installing to a 16GB partition is sufficient.
This guide covers for ***TrueNas Scale 24.04 to 25.10***
You can to modify the installer script before starting the installation process.
1. Boot TrueNAS Scale installer from USB/ISO
2. Select shell in the first menu (instead of installing)
3. While in the shell, find and open the installer and edit using vi
**For TrueNasScale before 24.10** - https://github.com/truenas/truenas-installer/blob/release/24.04.2.5/usr/sbin/truenas-install#L460
vi /usr/sbin/truenas-install
**For TrueNasScale 24.10+** - https://github.com/truenas/truenas-installer/blob/76a188e9048f26bca1a88f5d46a552742b3db286/truenas_installer/install.py#L81
vi /usr/lib/python3/dist-packages/truenas_installer/install.py
4. in vi you can use "set number" to easily see on what line of code you are
5. make the changes on line 81 as follows: `await run(["sgdisk", "-n3:0:+16GiB", "-t3:BF01", disk.device])`
6. exit vi and type exit to return from the shell
7. Select Install/Upgrade from the Console Setup menu (without rebooting, first) and install to NVMe drive.
8. Remove the USB and reboot.
Next we re-partition the nvme. You can perform this next setp on console or enable ssh via TrueNas Gui
1. Login to the linux shell.
2. Verify the created partition and their alignment
```bash
truenas_admin@truenas[~]$ sudo fdisk -l /dev/nvme0n1
Disk /dev/nvme0n1: 931.51 GiB, 1000204886016 bytes, 1953525168 sectors
Disk model: CT1000P3PSSD8
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 67X88FDC-3A4E-43FC-BA2F-AD279703FBFF
Device Start End Sectors Size Type
/dev/nvme0n1p1 4096 6143 2048 1M BIOS boot
/dev/nvme0n1p2 6144 1054719 1048576 512M EFI System
/dev/nvme0n1p3 1054720 34609151 33554432 16G Solaris /usr & Apple ZFS
truenas_admin@truenas[~]$ for p in 1 2 3; do sudo parted /dev/nvme0n1 align-check optimal $p; done
1 aligned
2 aligned
3 aligned
```
3. create a partition allocating the rest of the disk.
```bash
truenas_admin@truenas[~]$ sudo parted
(parted) name 3 boot-pool
(parted) unit KiB
(parted) print
(parted) mkpart ssd-pool 17304576kiB 100%
(parted) print
Model: CT1000P3PSSD8 (nvme)
Disk /dev/nvme0n1: 976762584kiB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 2048kiB 3072kiB 1024kiB bios_grub, legacy_boot
2 3072kiB 527360kiB 524288kiB fat32 boot, esp
3 527360kiB 17304576kiB 16777216kiB zfs boot-pool
4 17304576kiB 976761856kiB 959457280kiB ssd-pool
truenas_admin@truenas[~]$ for p in 1 2 3 4; do sudo parted /dev/nvme0n1 align-check optimal $p; done
1 aligned
2 aligned
3 aligned
4 aligned
```
4. setup the zpool for the UI to pick it up
`sudo zpool create ssd-pool /dev/nvme0n1p4`
`sudo zpool export ssd-pool`
NOTE: you can ignore the error message "cannot mount '/ssd-pool': failed to create mountpoint: Read-only file system"
5. use the TrueNas `Gui` -> Storage Dashboard -> `Import Pool`
# (Re-) Creating a mirrored Boot and Data Pool:
**IMPORTANT**: zpool replace does not recreate or copy the EFI boot partition!
*This need to be done manually!!!*
##### Step 1 — Completely wipe new drive/replacement drive/formerly used drive [eg.: nvme1n1]
This guarantees no stale metadata. (GPT + ZFS labels)
`
```language
sudo zpool labelclear -f /dev/nvme1n1
sudo wipefs -a /dev/nvme1n1
sudo sgdisk --zap-all /dev/nvme1n1
```
`
Verify:
`lsblk -f /dev/nvme1n1`
No filesystems, no partitions.
##### Step 2 — Clone the partition table
We do not use parted here!
We use sgdisk, which is what TrueNAS relies on internally.
`sudo sgdisk -R= `
`sudo sgdisk -G /dev/nvme1n1`
This:
*Copies GPT header
Copies all partition offsets
Preserves 1 MiB alignment
Makes layouts identical
In addition, regenerate unique disk GUIDs (required)*
```bash
truenas_admin@truenas[~]$ sudo sgdisk -R=/dev/nvme1n1 /dev/nvme0n1
The operation has completed successfully.
truenas_admin@truenas[~]$ sudo sgdisk -G /dev/nvme1n1
The operation has completed successfully.
truenas_admin@truenas[~]$ lsblk -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
nvme1n1
├─nvme1n1p1
├─nvme1n1p2 vfat FAT32 EFI 4E95-56BB
├─nvme1n1p3 zfs_member 5000 boot-pool 5995343355652310543
└─nvme1n1p4 zfs_member 5000 ssd-pool 8868205190042146147
nvme0n1
├─nvme0n1p1
├─nvme0n1p2 vfat FAT32 EFI 6165-92D6
├─nvme0n1p3 zfs_member 5000 boot-pool 3904092570291516174
└─nvme0n1p4 zfs_member 5000 ssd-pool 7548575174596316953
```
##### Step 3 — Verify layouts match exactly
`sudo sgdisk -p /dev/nvme0n1`
`sudo sgdisk -p /dev/nvme1n1`
The start/end sectors must match for:
p1 (BIOS_GRUB)
p2 (EFI)
p3 (boot-pool slice)
p4 (data slice)
Also check:
`lsblk -o NAME,START,SIZE /dev/nvme0n1 /dev/nvme1n1`
They should now be identical.
##### Step 4 — Attach nvme1n1p3 to the boot pool (CLI)
Lets add the new drives to the pool and create a mirror:
`sudo zpool attach `
This creates:
```bash
truenas_admin@truenas[~]$ sudo zpool attach boot-pool nvme0n1p3 nvme1n1p3
truenas_admin@truenas[~]$ zpool status boot-pool
pool: boot-pool
state: ONLINE
scan: resilvered 3.23G in 00:00:05 with 0 errors on Wed Mar 4 06:01:53 2026
config:
NAME STATE READ WRITE CKSUM
boot-pool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
nvme0n1p3 ONLINE 0 0 0
nvme1n1p3 ONLINE 0 0 0
```
Optional mirror the Data/Application Pool:
```bash
truenas_admin@truenas[~]$ sudo zpool attach ssd-pool nvme0n1p4 nvme1n1p4
truenas_admin@truenas[~]$ zpool status ssd-pool
pool: ssd-pool
state: ONLINE
scan: resilvered 2.21M in 00:00:00 with 0 errors on Thu Mar 5 06:14:42 2026
config:
NAME STATE READ WRITE CKSUM
ssd-pool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
nvme0n1p4 ONLINE 0 0 0
nvme1n1p4 ONLINE 0 0 0
```
**Recommended dataset layout for apps**
`sudo zfs set compression=zstd ssd-pool`
`sudo zfs set atime=off ssd-pool`
##### Step 5 — (IMPORTANT) Install EFI bootloader on nvme1n1
ZFS mirror alone is not enough — EFI must exist.
Confirm what /boot/efi really is right now
Run:
```bash
truenas_admin@truenas[~]$ sudo findmnt /boot/efi || true
truenas_admin@truenas[~]$ ls -ld /boot/efi
drwxr-xr-x 2 root root 2 Mar 3 23:58 /boot/efi
truenas_admin@truenas[~]$ sudo blkid /dev/nvme0n1p2 /dev/nvme1n1p2
/dev/nvme0n1p2: LABEL_FATBOOT="EFI" LABEL="EFI" UUID="6165-92D6" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="24657b7f-2cfa-44dc-842a-498c73e48478"
/dev/nvme1n1p2: LABEL_FATBOOT="EFI" LABEL="EFI" UUID="4E95-56BB" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="6ebe1b30-0ec9-47a6-82a9-a2cd11a2d2ef"
```
- If findmnt shows nothing → /boot/efi is not mounted (most likely).
- blkid should show TYPE="vfat" for the ESP partitions.
Instead of running grub-install, do what appliance systems commonly do:
Mount ESP on nvme0
Mount ESP on nvme1
Copy the EFI files
Optionally add a BIOS/UEFI boot entry for the new drive
##### A. Mount both ESPs
```bash
truenas_admin@truenas[~]$ sudo mkdir -p /mnt/esp0 /mnt/esp1
truenas_admin@truenas[~]$ sudo mount -t vfat /dev/nvme0n1p2 /mnt/esp0
truenas_admin@truenas[~]$ sudo mount -t vfat /dev/nvme1n1p2 /mnt/esp1
```
NOTE: If mounting /dev/nvme1n1p2 fails or it’s not vfat, reformat it (this erases only the esp partion on nvme1):
*sudo mkfs.vfat -F32 -n EFI /dev/nvme1n1p2
sudo mount -t vfat /dev/nvme1n1p2 /mnt/esp1*
##### B. Copy EFI contents from disk 0 to disk 1
`sudo rsync -aH --delete /mnt/esp0/ /mnt/esp1/
sync`
##### C. Make sure the “removable media” fallback exists (helps a lot)
Many firmwares will boot \EFI\BOOT\BOOTX64.EFI automatically if no NVRAM entry exists.
Check what TrueNAS placed on the ESP:
```bash
truenas_admin@truenas[~]$ sudo find /mnt/esp0/EFI -maxdepth 2 -type f -iname '*.efi' -print
/mnt/esp1/EFI/boot/bootx64.efi
/mnt/esp1/EFI/debian/fbx64.efi
/mnt/esp1/EFI/debian/grubx64.efi
/mnt/esp1/EFI/debian/mmx64.efi
/mnt/esp1/EFI/debian/shimx64.efi
```
If you see something like /mnt/esp0/EFI/debian/grubx64.efi (example), create the fallback:
```bash
truenas_admin@truenas[~]$ sudo mkdir -p /mnt/esp1/EFI/BOOT
truenas_admin@truenas[~]$ sudo cp -f /mnt/esp0/EFI/*/grubx64.efi /mnt/esp1/EFI/BOOT/BOOTX64.EFI
sync
```
(That EFI/*/grubx64.efi glob is deliberate so it works even if the vendor dir isn’t exactly truenas.)
##### D. Add an NVRAM boot entry for newDrive (Optional but recommended)
First, see existing entries:
```language
truenas_admin@truenas[~]$ sudo efibootmgr -v
BootCurrent: 0002
Timeout: 1 seconds
BootOrder: 0002,0000,0001,0003
Boot0000 Windows Boot Manager VenHw(99e275e7-75a0-4b37-a2e6-c5385e6c00cb)WINDOWS.........x...B.C.D.O.B.J.E.C.T.=.{.9.d.e.a.8.6.2.c.-.5.c.d.d.-.4.e.7.0.-.a.c.c.1.-.f.3.2.b.3.4.4.d.4.7.9.5.}...................
Boot0001 debian VenHw(99e275e7-75a0-4b37-a2e6-c5385e6c00cb)
Boot0002* debian HD(2,GPT,24657b7f-2cfa-44dc-842a-498c73e48478,0x1800,0x100000)/File(\EFI\debian\shimx64.efi)
Boot0003 TrueNAS (nvme1) VenHw(99e275e7-75a0-4b37-a2e6-c5385e6c00cb)
```
Then create a new one pointing to the copied loader (adjust the path to whatever you actually have on the ESP; use the find output you ran above):
```language
truenas_admin@truenas[~]$ sudo efibootmgr -c -d /dev/nvme0n1 -p 2 -L "TrueNAS (nvme1)" -l '\EFI\truenas\grubx64.efi'
BootCurrent: 0002
Timeout: 1 seconds
BootOrder: 0004,0002,0000,0001,0003
Boot0000 Windows Boot Manager
Boot0001 debian
Boot0002* debian
Boot0003 TrueNAS (nvme1)
Boot0004* TrueNAS (nvme1)
```
##### E. Unmount
`sudo umount /mnt/esp0 /mnt/esp1`
##### F. Validate EFI Bootmanager
```bash
truenas_admin@truenas[~]$ sudo efibootmgr -v
BootCurrent: 0003
Timeout: 1 seconds
BootOrder: 0006,0005,0003,0000,0001,0002,0004
Boot0000 Windows Boot Manager VenHw(99e275e7-75a0-4b37-a2e6-c5385e6c00cb)WINDOWS.........x...B.C.D.O.B.J.E.C.T.=.{.9.d.e.a.8.6.2.c.-.5.c.d.d.-.4.e.7.0.-.a.c.c.1.-.f.3.2.b.3.4.4.d.4.7.9.5.}...................
Boot0001 debian VenHw(99e275e7-75a0-4b37-a2e6-c5385e6c00cb)
Boot0002 debian VenHw(99e275e7-75a0-4b37-a2e6-c5385e6c00cb)
Boot0003* debian HD(2,GPT,51003091-0620-4c18-868c-ea9dba1f564e,0x1800,0x100000)/File(\EFI\debian\shimx64.efi)
Boot0004 TrueNAS (nvme1) VenHw(99e275e7-75a0-4b37-a2e6-c5385e6c00cb)
Boot0005* TrueNAS (nvme1) HD(2,GPT,ff4dba6e-93b9-45ea-b546-33c28c63f612,0x1800,0x100000)/File(\EFI\truenas\grubx64.efi)
Boot0006* TrueNAS (nvme1) HD(2,GPT,51003091-0620-4c18-868c-ea9dba1f564e,0x1800,0x100000)/File(\EFI\truenas\grubx64.efi)
```
NOTE: as this is my 3rd iteration, Boot0004 is not a proper file path (it shows VenHw) meaning it's probably stale, so removed it.
```bash
truenas_admin@truenas[~]$ sudo efibootmgr -b 0003 -B
BootCurrent: 0002
Timeout: 1 seconds
BootOrder: 0004,0002,0000,0001
Boot0000 Windows Boot Manager
Boot0001 debian
Boot0002* debian
Boot0004* TrueNAS (nvme1)
```
##### G. Now you can test by removing the a Drive from the Mirror and reboot the system
Drive goes into degraded state after pulling Drive2
```language
truenas_admin@truenas[~]$ sudo zpool status
pool: boot-pool
state: DEGRADED
config:
NAME STATE READ WRITE CKSUM
boot-pool DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
15318324978903853925 FAULTED 0 0 0 was /dev/nvme0n1p3
nvme0n1p3 ONLINE 0 0 0
pool: ssd-pool
state: DEGRADED
config:
NAME STATE READ WRITE CKSUM
ssd-pool DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
2513775003968519971 FAULTED 0 0 0 was /dev/nvme0n1p4
nvme0n1p4 ONLINE 0 0 0
```
ZFS is switching on how it displays a vdev when the normal device path is missing, so you'll a long number instead of nvme1n1p3
Those long numbers like [2513775003968519971] are ZFS vdev GUIDs.
ZFS stores devices internally by GUID. When the OS device node (like /dev/nvme1n1p3) is missing/unavailable, ZFS can’t resolve it to a path, so it shows the GUID instead.
You would simply de-tach the FAULTY Drives
```bash
truenas_admin@truenas[~]$ sudo zpool detach ssd-pool 2513775003968519971
truenas_admin@truenas[~]$ sudo zpool detach boot-pool 15318324978903853925
truenas_admin@truenas[~]$ zpool status
pool: boot-pool
state: ONLINE
scan: resilvered 3.23G in 00:00:06 with 0 errors on Thu Mar 5 06:11:03 2026
config:
NAME STATE READ WRITE CKSUM
boot-pool ONLINE 0 0 0
nvme0n1p3 ONLINE 0 0 0
errors: No known data errors
pool: ssd-pool
state: ONLINE
scan: resilvered 2.21M in 00:00:00 with 0 errors on Thu Mar 5 06:14:42 2026
config:
NAME STATE READ WRITE CKSUM
ssd-pool ONLINE 0 0 0
nvme0n1p4 ONLINE 0 0 0
```
NOTE: Make sure you identify the device names correctly as they might change, so check your zpool before!
The correct way to reference disks when running manual ZFS commands you should never rely on /dev/nvmeX.
Instead use stable paths: /dev/disk/by-id/
Check them:
ls -l /dev/disk/by-id/ | grep -i nvme
ls -l /dev/disk/by-id/ | grep -E 'part3|part4'
## After the drive-replacement, start from top again by (Re-) Creating a mirrored Boot and Data Pool