How to Expand a ZFS RAIDZ Pool on Proxmox Without Rebuilding the Array

Updated on Oct 14, 2026
Mila H
14 MINS READ
Table of Contents
Expand a ZFS RAIDZ Pool on Proxmox

Running out of space on your RAIDZ pool is stressful, especially when you do not want to rebuild it from zero. With Proxmox VE 9 and newer, you can add a new disk to your current RAIDZ vdev using one zpool attach command, and your VMs keep running the whole time. In this guide, you will learn how to expand a ZFS RAIDZ pool on Proxmox step by step.

How RAIDZ Expansion Works and Where It Stops

RAIDZ expansion is a ZFS feature that lets you attach a new disk to an existing RAIDZ vdev. ZFS reads all the data in the vdev and rewrites it across the old disks plus the new one. The pool stays online during this work, and your data stays protected.

Before you expand a ZFS RAIDZ pool on Proxmox, it is better to know what the feature can and cannot do:

Question Answer
Can I add more than one disk at once? No. Add one disk, wait for it to finish, then add the next.
Can I change RAIDZ1 to RAIDZ2? No. A RAIDZ1 stays RAIDZ1.
Can I undo it? No. You cannot remove the disk or cancel the expansion later.
Does the pool stay online? Yes. VMs and containers keep running.
Is old data moved to the new layout right away? No. Old data keeps its old data-to-parity ratio.

Requirements Before You Start

To expand a ZFS RAIDZ pool on Proxmox, you need all of these:

  • Proxmox VE 9.0 or newer. 
  • One free slot and a new disk that is the same size or bigger.
  • A healthy pool with no errors.
  • A real backup on another machine or storage.
  • Root access to the Proxmox host.

If you are still on Proxmox VE 8, you must upgrade to version 9. Then, update the system:

Bash
apt updateapt full-upgrade -yreboot

After the reboot, verify you have the latest versions:

Bash
pveversionzfs version

You must see zfs-2.3.x or newer. Older versions cannot do RAIDZ expansion.

Warning: This guide is for data pools. Do not enable new ZFS features on a boot pool (rpool) if your server still boots with GRUB. It can make the server unbootable. Check the proxmox-boot-tool status.

Safe Steps to Expand a ZFS RAIDZ Pool on Proxmox

Now you are ready to add the new disk. First, you must check the pool and make a backup. Then add the disk, watch the progress, and check the result. The examples use tank as the pool name and raidz1-0 as the vdev name, so change them to match your system.

Step 1: Create a Pre-Check Script

This small script prints everything you need to know before you expand a ZFS RAIDZ pool on Proxmox. Create the file with your desired editor:

Bash
nano /root/zfs-precheck.sh

Paste this inside the file, then save with Ctrl+O, Enter, and exit with Ctrl+X:

Bash
#!/bin/bashPOOL="${1:?Usage: $0 <pool>}" echo "== Proxmox version =="pveversionechoecho "== ZFS version =="zfs versionechoecho "== RAIDZ expansion feature =="zpool get feature@raidz_expansion "$POOL"echoecho "== Pool health =="zpool status -x "$POOL"echoecho "== Pool layout and size =="zpool list -v "$POOL"echoecho "== Space details =="zfs list -o space "$POOL"echoecho "== Snapshot count =="zfs list -H -t snapshot -r -o name "$POOL" | wc -l

Make the script executable and run it with the commands below:

Bash
chmod +x /root/zfs-precheck.sh/root/zfs-precheck.sh tank

Save the output. We will compare it with the result after the expansion.

Step 2: Check Feature Support

RAIDZ expansion only works when the raidz_expansion feature is turned on for your pool. Check its status with the command below:

Bash
zpool get feature@raidz_expansion tank

You will see one of these values:

  • enabled: ready to use.
  • active: the pool was already expanded once. You can expand again.
  • disabled: the pool feature is off. Turn it on in the next step.

If the value is disabled, enable only this feature with the command below:

Bash
zpool set feature@raidz_expansion=enabled tank

Be careful here. After you use this feature, the pool cannot be imported by older ZFS versions. This includes older Proxmox kernels and older Proxmox ISO rescue disks. Keep a newer rescue system if you may need one.

If you try to attach a disk without enabling the feature, ZFS shows an error like this: raidz_expansion feature must be enabled in order to attach a device to raidz.

Step 3: Check Pool Health

Never try to expand a ZFS RAIDZ pool on Proxmox when the pool has errors. Check the pool health status with:

Bash
zpool status -v tank

You must see state: ONLINE and errors: No known data errors. Then, check the disks with SMART:

Bash
apt install smartmontools -ysmartctl -a /dev/sda | head -n 40

Repeat the SMART check for every disk in the vdev. Replace any disk that shows reallocated or pending sectors before you continue.

Then, run a full scrub and wait for it to end:

Bash
zpool scrub tankzpool wait -t scrub tankzpool status -v tank

The scrub should end with 0 errors.

Step 4: Back Up Before You Expand

A snapshot on the same pool is not a backup. If the pool is lost, the snapshot is lost too. You must copy your data to another machine or storage before you expand a ZFS RAIDZ pool on Proxmox. First, make a recursive snapshot:

Bash
zfs snapshot -r tank@pre-expand

Then, send it to another server over SSH. Replace the user, host, and target pool:

Bash
zfs send -R tank@pre-expand | ssh root@backup-host zfs receive -u -F backup/tank-copy

For VMs, you can also use Proxmox backups. Replace 100 with your VM ID and backup-store with your backup storage name:

Bash
vzdump 100 --storage backup-store --mode snapshot --compress zstd

Now check that the backup exists with the following command:

Bash
ssh root@backup-host zfs list -t snapshot -r backup/tank-copy

Rollback limit: Snapshots and backups protect your data. They do not undo the expansion. The pool layout cannot go back to the old width. If something goes very wrong, the only way back is to rebuild the pool and restore from your backup.

Step 5: Make Free Space on the Pool

Your pool is full, so you must make some space before you start. A very full pool is slow and risky. First, look at where the space goes:

Bash
zfs list -o space -r tankzfs list -t snapshot -r -o name,used -s used tank

Then, delete old snapshots you no longer need. You can test with -n -v to see what would be removed:

Bash
zfs destroy -n -v tank/vmdata@old-snapshotzfs destroy tank/vmdata@old-snapshot

Step 6: Prepare the New Disk

At this point, you can install the new disk in the free slot. Then, you must find its stable ID. Do not use /dev/sdX names, because they can change after a reboot:

Bash
lsblk -o NAME,SIZE,MODEL,SERIALls -l /dev/disk/by-id/ | grep -v part

Pick the ID that matches the model and serial number of your new disk. You can check it with SMART:

Bash
smartctl -a /dev/disk/by-id/ata-EXAMPLE_DISK_SERIAL | head -n 40

If the disk was used before, you must clear the old labels. This command deletes data on the disk, so be sure it is the right one:

Bash
wipefs -a /dev/disk/by-id/ata-EXAMPLE_DISK_SERIALsgdisk --zap-all /dev/disk/by-id/ata-EXAMPLE_DISK_SERIAL

Next, find the exact RAIDZ vdev name. You need the vdev name, such as raidz1-0, not the pool name:

Bash
zpool status tank
Bash
#Example Output:   pool: tank state: ONLINEconfig:         NAME                        STATE     READ WRITE CKSUM        tank                        ONLINE       0     0     0          raidz1-0                  ONLINE       0     0     0            ata-DISK_SERIAL_1       ONLINE       0     0     0            ata-DISK_SERIAL_2       ONLINE       0     0     0            ata-DISK_SERIAL_3       ONLINE       0     0     0            ata-DISK_SERIAL_4       ONLINE       0     0     0

Step 7: Add the Disk to the RAIDZ Vdev

This is the main step. You can use the zpool attach command to add the new disk to your RAIDZ vdev. The command returns fast, and ZFS does the expansion in the background while your pool stays online:

Bash
zpool attach tank raidz1-0 /dev/disk/by-id/ata-EXAMPLE_DISK_SERIAL

If you want the command to wait until it finishes, add -w:

Bash
zpool attach -w tank raidz1-0 /dev/disk/by-id/ata-EXAMPLE_DISK_SERIAL

If you use -w, you can run it inside tmux so an SSH drop does not stop your view:

Bash
apt install tmux -ytmux new -s zfs-expand

Step 8: Monitor the Expansion

The expansion can take many hours, so watch it while it runs. Check the progress with the command below:

Bash
zpool status -v tank

You will see an expand: line like this:

Bash
expand: expansion of raidz1-0 in progress since Sat Oct 10 12:30:00 2026        1.31T / 3.02T copied at 412M/s, 43.38% done, 01:12:44 to go

Watch it live and see the disk load for each disk with the commands below:

Bash
watch -n 10 zpool status tankzpool iostat -v tank 10

Also, you can save the progress to a log file with a small script. Create the file with the command below:

Bash
nano /root/zfs-expand-log.sh

Paste this inside the file, then save with Ctrl+O, Enter, and exit with Ctrl+X:

Bash
#!/bin/bashPOOL="${1:?Usage: $0 <pool>}"LOG="/var/log/zfs-expand-$POOL.log"while true; do  date >> "$LOG"  zpool status "$POOL" | grep -A2 -E "expand:|scan:" >> "$LOG"  sleep 300done

Make it executable, run it in the background, and check the logs with the commands below:

Bash
chmod +x /root/zfs-expand-log.shnohup /root/zfs-expand-log.sh tank >/dev/null 2>&1 &tail -f /var/log/zfs-expand-tank.log

Stop it with the following command when the work is done:

Bash
pkill -f zfs-expand-log.sh

Things to know during the expansion:

  • The time depends on how much data is in the vdev and how fast the disks are.
  • Your VMs keep running, but disk speed will be lower.
  • If you reboot or export and import the pool, the expansion continues where it stopped.
  • If a disk fails during the work, the expansion pauses until the vdev is healthy again. Replace the disk with zpool replace, let it rebuild, and the expansion continues.
  • Do not start your own scrub now. ZFS runs a pool-wide scrub by itself at the end of the expansion to check all copied data.

Step 9: Add More Disks (Optional)

To add another disk, you must wait until the expansion and the scrub both finish. Then, repeat Steps 3, 6, and 7 with the next disk:

Bash
zpool attach tank raidz1-0 /dev/disk/by-id/ata-SECOND_NEW_DISK

You can expand a RAIDZ vdev many times, but you can add only one disk each time.

Confirm the Pool Is Healthy After ZFS RAIDZ Expansion

After you expand a ZFS RAIDZ pool on Proxmox, you must wait for both the expansion and the automatic scrub to end. Then, run these checks:

Bash
zpool status -v tank

Look for these signs:

  • state: ONLINE.
  • The expand: line says the expansion is completed.
  • The scan: line says scrub repaired 0B with 0 errors.
  • All disks show 0 in the READ, WRITE, and CKSUM columns.
  • The new disk is listed inside the same RAIDZ vdev.

Then, check the new size; the feature should now say active:

Bash
zpool list -v tankzfs list -o space tankzpool get feature@raidz_expansion tank

Also, you can run your pre-check script again and compare it with the first result:

Bash
/root/zfs-precheck.sh tank

Check that Proxmox sees the storage and the new space:

Bash
pvesm status

Proxmox uses the pool through its storage entry, so you do not need to change the storage setting. The new space shows up by itself. Finally, check SMART on the new disk after a few days:

Bash
smartctl -H /dev/disk/by-id/ata-EXAMPLE_DISK_SERIAL

Capacity and Performance Limits of RAIDZ Expansion

Adding a disk gives you more space, but it does not work like a fresh pool. Old data keeps its old layout, so you may see less free space than you expect. Speed for VMs also stays about the same. This section explains why, and how to fix it.

You May See Less Space Than You Expect

After the expansion, old data keeps its old data-to-parity ratio. For example, a 5-disk RAIDZ2 stores old blocks as 3 data and 2 parity. After you expand it to 6 disks, new blocks use 4 data and 2 parity.

Also, ZFS keeps the old "assumed" ratio for reporting, so zfs list and df can show slightly less free space than you expect.

This is normal and it is not a bug. Your old data is safe. It is just not as space-efficient as new data.

How to Get the Space Back

You can rewrite old data so it uses the new ratio. You have three options:

  1. Use zfs rewrite (ZFS 2.4 or newer). This command rewrites files in place. It does not work on ZFS 2.3.x.
  2. Use zfs send and zfs receive. Copy a dataset to a new dataset on the same pool, check it, then remove the old one.
  3. Move VM disks. For VM disks (zvols), move the disk to another storage and back.

First, use the command below to check your ZFS version:

Bash
zfs version

On ZFS 2.4 or newer, you can rewrite a dataset folder like this:

Bash
zfs rewrite -r -v /tank/data

The -P option keeps the file change times, so incremental backups stay small. It needs the physical_rewrite feature on the pool. Read man zfs-rewrite before you use it.

Snapshots can hold the old blocks. When you rewrite data that is in a snapshot, the old and new copies both use space for a while. So rewrite in small parts, and watch free space with zfs list -o space tank. Pause automatic snapshots while you do this.

For the send and receive method, you can use:

Bash
zfs snapshot tank/data@rebalancezfs send tank/data@rebalance | zfs receive tank/data-new

After you check the new dataset, stop anything that writes to the old one, then swap the names:

Bash
zfs rename tank/data tank/data-oldzfs rename tank/data-new tank/data

Delete tank/data-old only when you are sure everything works. This method needs enough free space for a full copy of the dataset, so it fits best when you can free up space.

To move a VM disk with Proxmox, use a second storage and move it back later. Replace the VM ID, disk name, and storage name:

Bash
qm disk move 100 scsi0 other-storage --delete 1qm disk move 100 scsi0 tank-vm --delete 1

Speed Does Not Improve Much

Adding a disk gives you more space and more read and write bandwidth. It does not give you more IOPS. Proxmox says a RAIDZ vdev behaves about like a single disk for IOPS. VMs usually care more about IOPS than bandwidth.

If your VMs feel slow, expansion will not fix it. A second vdev, mirrors, or tuning may help more. For tuning ideas such as block size, ARC size, and compression, read our Proxmox ZFS optimization guide.

Wider Vdevs Add Risk

A wider RAIDZ1 still survives only one failed disk. The more disks you add, the higher the chance that a second disk fails during a rebuild. For many disks, RAIDZ2 is safer, but you cannot convert RAIDZ1 to RAIDZ2 with expansion.

More Limits to Know

There are a few more limits you should know before you start. Some things cannot be changed after the expansion.

  • Expansion does not change ashift. If the vdev was built with a bad ashift, expansion will not fix it.
  • You cannot remove the disk after the expansion.
  • You cannot make the pool smaller.
  • If you need more IOPS or want to add many disks at once, consider adding a second vdev instead. Use -n first for a dry run. Adding a RAIDZ vdev to a pool cannot be undone:
Bash
zpool add -n tank raidz1 /dev/disk/by-id/disk-A /dev/disk/by-id/disk-B /dev/disk/by-id/disk-C

Conclusion

At this point, you have learned to expand a ZFS RAIDZ pool on Proxmox without rebuilding it. Check that you run Proxmox VE 9 with ZFS 2.3 or newer, confirm feature@raidz_expansion, back up your data, then run zpool attach with the disk ID. Watch zpool status until the expansion and the scrub finish. Remember that old data keeps its old ratio, the change cannot be undone, and IOPS stay about the same.

If your server has no free slots, you must plan the next step. You can choose a dedicated server with extra NVMe or SSD capacity from PerLod, so you have room to grow your virtual storage.

Proxmox VE 9.0 and newer, because they include ZFS 2.3 or newer.

No. You can expand a ZFS RAIDZ pool on Proxmox online, but the disk speed is lower until it finishes.

No. You cannot cancel it or remove the disk later. Only a backup restore can bring back the old layout.

The expansion continues after the pool is imported again.

ZFS starts one by itself at the end. Wait for it to finish and check for zero errors.