| Tested on | Linux VM lab (VirtualBox) |
|---|---|
| Package | parted 3.2util-linux 2.32.1 (fdisk)e2fsprogs 1.44.3 (resize2fs) |
| Applies to | RHEL, Rocky Linux, AlmaLinux, CentOS Stream, Fedora, Debian, Ubuntu, and other Linux distributions with parted, fdisk, and ext4/XFS tools |
| Privilege | root (partition table and filesystem changes) |
| Scope | Extend a non-LVM primary root partition into trailing unallocated space using parted or fdisk, then grow ext4 with resize2fs; includes swap removal and recreation when swap is the last partition |
| Related guides | Extend an LVM partition parted command Create a filesystem on a partition Back up a Linux partition df and du commands |
To extend a root partition on a disk without LVM, you grow the
partition table entry into unallocated space, then run a filesystem
grow tool so df reflects the new size. On ext4 that is resize2fs;
on XFS use xfs_growfs on the mount point.
This walkthrough covers two CLI paths: GNU parted and fdisk. Both
were tested on a lab VM where / lived on /dev/sda2 with swap on
/dev/sda3 and free space at the end of /dev/sda.
Quick reference: extend a non-LVM root partition
| Step | Action |
|---|---|
| 1 | Confirm unallocated space exists after the partition you need to grow |
| 2 | Back up data; ensure the target partition can become the last one on the disk |
| 3 | swapoff -a and comment swap out of /etc/fstab if swap blocks growth |
| 4 | Delete and recreate the root partition with the same start sector, larger end |
| 5 | resize2fs /dev/sdXN (ext4) or xfs_growfs / (XFS) while mounted |
| 6 | Recreate swap at the end of the disk; mkswap, update /etc/fstab, swapon |
| 7 | Reboot once to confirm the layout after partition-table changes |
| Tool | Best when |
|---|---|
parted |
You prefer sector-exact sizing and scripted mkpart syntax |
fdisk |
fdisk is already familiar; MBR/GPT editing on traditional layouts |
If the root filesystem already sits on LVM, use volume-group extension instead of editing primary partition entries.
Before you resize: scope and risks
sfdisk --dump before you change the
partition table. These steps assume GPT or MBR primary partitions
and contiguous unallocated space immediately after the partition you
grow.
You can only extend a primary partition into free space that sits directly after it on the same disk. When swap blocks that gap:
- Turn swap off and remove its partition table entry
- Grow root into the trailing unallocated region
- Recreate swap at the end of the disk
The lab layout used throughout this article:
/dev/sda1—/boot(ext4)/dev/sda2—/root (ext4, non-LVM)/dev/sda3— swap- trailing unallocated space on
/dev/sda
The same workflow applies on physical servers and cloud VMs after you
expand the virtual disk; grow the disk in the hypervisor or cloud
console first so unallocated sectors appear at the end of /dev/sda.
Lab environment
The commands below were captured on a VirtualBox lab VM with an MBR
(msdos) partition table. Device names (/dev/sda) and sector numbers
in the transcripts match that lab layout; run parted -l or fdisk -l
on your host before you edit.
Method 1: Extend root with parted
parted edits the partition table in sector units, which helps avoid
rounding errors when you extend a root partition without LVM. You can
also use the GParted GUI; this section sticks to the CLI shown in the
tested output.
For parted syntax and flags outside this resize workflow, see the
parted command cheat sheet.
List partitions on the disk
Start by printing the current layout of /dev/sda:
[root@lab ~]# parted -l /dev/sda
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 16.1GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags <--- This is my partition layout
1 1049kB 538MB 537MB primary ext4 boot
2 538MB 11.3GB 10.7GB primary ext4
3 11.3GB 12.3GB 1074MB primary linux-swap(v1)Root (/dev/sda2) is not the last partition — swap (/dev/sda3)
sits after it. To reach the unallocated space at the end of the disk,
swap must be removed temporarily so root can become the last partition
before you extend it.
Disable swap
Check how much swap is active:
[root@lab ~]# free -m
total used free shared buff/cache available
Mem: 3781 164 3245 8 371 3389
Swap: 1023 0 1023Turn swap off before editing the partition table:
[root@lab ~]# swapoff -aSwap should now read zero in the free -m output:
[root@lab ~]# free -m
total used free shared buff/cache available
Mem: 3781 164 3241 8 375 3389
Swap: 0 0 0Comment out the swap line in /etc/fstab so the system does not
mount swap at boot during the resize session:
[root@lab ~]# cat /etc/fstab
UUID=b3ba77fc-86a7-40dc-a93e-402d8e3987ab / ext4 defaults 1 1
UUID=621d26e4-4bcc-441d-b336-a9bae280343d /boot ext4 defaults 1 2
#UUID=3816d191-31fd-4e20-874d-b18360133aca swap swap defaults 0 0Delete swap and grow the root partition
Open parted on /dev/sda. The interactive session below:
- deletes swap
- switches to sector units
- records root's start sector
- removes and recreates root with a larger end sector
When parted warns the kernel still holds the old table, choose Ignore and continue — do not reboot mid-session.
[root@lab ~]# parted /dev/sda
GNU Parted 3.2
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) p
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 16.1GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1049kB 538MB 537MB primary ext4 boot
2 538MB 11.3GB 10.7GB primary ext4
3 11.3GB 12.3GB 1074MB primary linux-swap(v1)
(parted) rm 3 <-- First we need to delete swap partition
(parted) p
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 16.1GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1049kB 538MB 537MB primary ext4 boot
2 538MB 11.3GB 10.7GB primary ext4
(parted) u <-- Change the unit type to sector to avoid any risk of loosing data when you resize root partition
Unit? [compact]? s
(parted) p <-- Print the available partition table
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 31457280s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 2048s 1050623s 1048576s primary ext4 boot
2 1050624s 22022143s 20971520s primary ext4 <--- Note down the start sector number, this will be used in next step
(parted) rm 2 <-- We will delete the root partition's entry. This will not impact the content of root partition and only partition table is modified.
Warning: Partition /dev/sda2 is being used. Are you sure you want to continue?
Yes/No? Yes
Error: Partition(s) 2 on /dev/sda have been written, but we have been unable to inform the kernel of the change, probably because
it/they are in use. As a result, the old partition(s) will remain in use. You should reboot now before making further changes.
Ignore/Cancel? Ignore <-- If you reboot your server at this stage then you may end up with a broken node so don't reboot your node at this stage.
(parted) p <-- Print the current partition table
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 31457280s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 2048s 1050623s 1048576s primary ext4 boot
(parted) mkpart <-- Now we will create root partition with new size
Partition type? primary/extended? primary
File system type? [ext2]? ext4
Start? 1050624s <-- Here give the start sector as it was earlier for root partition
End? 24022143s <-- Give the new end sector higher than the earlier value to resize root partition
(parted) p <-- Print the new partition table after you extend non lvm root partition
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 31457280s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 2048s 1050623s 1048576s primary ext4 boot
2 1050624s 24022143s 22971520s primary ext4 lba
(parted) quit <-- We are all done here
Information: You may need to update /etc/fstab.The partition table now lists a larger /dev/sda2, but df still
shows the old filesystem size until you grow ext4:
[root@lab ~]# df -h /dev/sda2
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 9.8G 1.2G 8.1G 13% /Run resize2fs on the mounted ext4 root device (use xfs_growfs /
for XFS instead):
[root@lab ~]# resize2fs /dev/sda2
resize2fs 1.44.3 (10-July-2018)
Filesystem at /dev/sda2 is mounted on /; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 2
The filesystem on /dev/sda2 is now 2871440 (4k) blocks long.Confirm the root filesystem picked up the extra space:
[root@lab ~]# df -h /dev/sda2
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 11G 1.3G 9.0G 12% /Recreate the swap partition
Create a new swap partition at the end of the disk with parted:
[root@lab ~]# parted /dev/sda
GNU Parted 3.2
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) mkpart
Partition type? primary/extended? primary
File system type? [ext2]? linux-swap <-- To create swap partition
Start?
Start? 24022144s
End? 98%
Warning: The resulting partition is not properly aligned for best performance: 24022144s % 2048s != 0s
Ignore/Cancel? Ignore
(parted) p
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 16.1GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1049kB 538MB 537MB primary ext4 boot
2 538MB 12.3GB 11.8GB primary ext4
3 12.3GB 12.8GB 512MB primary linux-swap(v1) lba <-- Now we have a swap partition
(parted) quit
Information: You may need to update /etc/fstab.Format the swap area and note the new UUID:
[root@lab ~]# mkswap /dev/sda3
Setting up swapspace version 1, size = 488.3 MiB (511995904 bytes)
no label, UUID=decb7df5-8d7a-41b4-bfd7-bee076006ec9Read the UUID back with blkid before you edit /etc/fstab:
[root@lab ~]# blkid /dev/sda3
/dev/sda3: UUID="decb7df5-8d7a-41b4-bfd7-bee076006ec9" TYPE="swap" PARTUUID="5290bf38-03"Add the UUID to /etc/fstab:
[root@lab ~]# cat /etc/fstab
UUID=b3ba77fc-86a7-40dc-a93e-402d8e3987ab / ext4 defaults 1 1
UUID=621d26e4-4bcc-441d-b336-a9bae280343d /boot ext4 defaults 1 2
UUID=3816d191-31fd-4e20-874d-b18360133aca swap swap defaults 0 0Enable swap:
[root@lab ~]# swapon /dev/sda3Verify swap is active again:
[root@lab ~]# free -m
total used free shared buff/cache available
Mem: 3781 155 3390 8 235 3407
Swap: 488 0 488Reboot when finished to confirm the system boots cleanly with the new layout.
Method 2: Extend root with fdisk
fdisk follows the same logic as Method 1: remove swap, delete and
recreate root with an unchanged start sector and a larger size, write
the table, grow the filesystem, then add swap back.
List partitions
Inspect /dev/sda before making changes:
[root@lab ~]# fdisk -l /dev/sda
Disk /dev/sda: 15 GiB, 16106127360 bytes, 31457280 sectors
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: dos
Disk identifier: 0x5290bf38
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 1050623 1048576 512M 83 Linux
/dev/sda2 1050624 22022143 20971520 10G 83 Linux <-- This is our root partition
/dev/sda3 22022144 24119295 2097152 1G 82 Linux swap / SolarisRoot is about 10 GiB in this lab snapshot:
[root@lab ~]# df -h /dev/sda2
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 9.8G 1.3G 8.1G 14% /Turn off swap and open fdisk
Swap must be off while the partition table is edited. Confirm it is still active:
[root@lab ~]# free -m
total used free shared buff/cache available
Mem: 3781 165 3243 8 372 3388
Swap: 1023 0 1023Then disable swap before opening fdisk:
[root@lab ~]# swapoff -aIn the fdisk session below:
- delete partition 3 (swap)
- delete partition 2 (root table entry only — data stays on disk)
- recreate root with the same first sector and a larger size
- add a new swap partition and set type
82
[root@lab ~]# fdisk /dev/sda
Welcome to fdisk (util-linux 2.32.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): p <-- Print the partition table
Disk /dev/sda: 15 GiB, 16106127360 bytes, 31457280 sectors
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: dos
Disk identifier: 0x5290bf38
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 1050623 1048576 512M 83 Linux
/dev/sda2 1050624 22022143 20971520 10G 83 Linux
/dev/sda3 22022144 24119295 2097152 1G 82 Linux swap / Solaris
Command (m for help): d <-- To delete a partition ude 'd'
Partition number (1-3, default 3): 3 <-- Provide the partition number which you wish to delete. Here our swap partition number is 3
Partition 3 has been deleted.
Command (m for help): p <-- Next we will print the new partition table again
Disk /dev/sda: 15 GiB, 16106127360 bytes, 31457280 sectors
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: dos
Disk identifier: 0x5290bf38
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 1050623 1048576 512M 83 Linux
/dev/sda2 1050624 22022143 20971520 10G 83 LinuxRecreate root inside fdisk
The next block continues the same fdisk session: delete root's
table entry, recreate it with first sector 1050624 and size +11G,
and keep the existing ext4 signature when prompted:
Command (m for help): d <-- Now we need to delete root partition before we extend non lvm root partition. This will not impact the content stored in root partition and will only clear the partition table.
Partition number (1,2, default 2): 2 <-- provide the root's partition number
Partition 2 has been deleted.
Command (m for help): p <-- Print the partition table with the new changes
Disk /dev/sda: 15 GiB, 16106127360 bytes, 31457280 sectors
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: dos
Disk identifier: 0x5290bf38
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 1050623 1048576 512M 83 Linux <-- Now we only have a boot partition
Command (m for help): n <-- Next we will create and expand partition for root
Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p): p <-- This will be a primary partition
Partition number (2-4, default 2): 2 <-- For root partition we know the partition number was 2 so we will use the same as it is important to use the same start sector
First sector (1050624-31457279, default 1050624): 1050624 <-- Use the same first sector as it was earlier to resize root partition
Last sector, +sectors or +size{K,M,G,T,P} (1050624-31457279, default 31457279): +11G <-- Here you can define the new size to resize root partition and expand partition
Created a new partition 2 of type 'Linux' and of size 11 GiB.
Partition #2 contains a ext4 signature.
Do you want to remove the signature? [Y]es/[N]o: N <-- Since we want to retain ext4 signature on our root partition we will use "N"
Command (m for help): p <-- Now print the new partition table once resize root partition is successful
Disk /dev/sda: 15 GiB, 16106127360 bytes, 31457280 sectors
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: dos
Disk identifier: 0x5290bf38
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 1050623 1048576 512M 83 Linux
/dev/sda2 1050624 24119295 23068672 11G 83 Linux <-- We have our new root partition with 11G as new sizeAdd swap back in fdisk
Still in the same session, create a 512 MiB swap partition and set
hex type 82:
Command (m for help): n <-- Now we will also create a new swap partition
Partition type
p primary (2 primary, 0 extended, 2 free)
e extended (container for logical partitions)
Select (default p): p <-- This also will be a primary partition
Partition number (3,4, default 3): 3 <-- We can give any partition number here but we will use 3 as earlier
First sector (24119296-31457279, default 24119296): <-- This can be the same as default option
Last sector, +sectors or +size{K,M,G,T,P} (24119296-31457279, default 31457279): +512M <--- My new swap partition size will be 512MB
Created a new partition 3 of type 'Linux' and of size 512 MiB.
Command (m for help): p <-- Print the new partition table
Disk /dev/sda: 15 GiB, 16106127360 bytes, 31457280 sectors
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: dos
Disk identifier: 0x5290bf38
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 1050623 1048576 512M 83 Linux
/dev/sda2 1050624 24119295 23068672 11G 83 Linux
/dev/sda3 24119296 25167871 1048576 512M 83 Linux <-- Now resize root partition was successful and we have all the partitions with us
Command (m for help): t <-- We must also change the filesystem type of our swap partition
Partition number (1-3, default 3): 3 <-- This is our swap partition
Hex code (type L to list all codes): 82 <-- 82 is the code for Linux swap filesystem type
Changed type of partition 'Linux' to 'Linux swap / Solaris'.
Command (m for help): p <-- Print the partition table to verify the new changes
Disk /dev/sda: 15 GiB, 16106127360 bytes, 31457280 sectors
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: dos
Disk identifier: 0x5290bf38
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 1050623 1048576 512M 83 Linux
/dev/sda2 1050624 24119295 23068672 11G 83 Linux
/dev/sda3 24119296 25167871 1048576 512M 82 Linux swap / Solaris
Command (m for help): w <-- Save the new partition table with the changes to expand partition
The partition table has been altered.
Syncing disks.Write the table with w, then refresh the kernel's view of the disk:
[root@lab ~]# partprobe /dev/sdaUntil swap is formatted and enabled, free shows no swap:
[root@lab ~]# free -m
total used free shared buff/cache available
Mem: 3781 164 3238 8 378 3389
Swap: 0 0 0Create swap on the new partition:
[root@lab ~]# mkswap /dev/sda3
Setting up swapspace version 1, size = 512 MiB (536866816 bytes)
no label, UUID=f34150e6-6d37-448c-b81f-69ecdcb13ed5Copy the UUID from blkid into /etc/fstab:
[root@lab ~]# blkid /dev/sda3
/dev/sda3: UUID="f34150e6-6d37-448c-b81f-69ecdcb13ed5" TYPE="swap" PARTUUID="5290bf38-03"Update /etc/fstab with the new swap UUID (you can also manage mounts
with systemd mount units
instead of fstab):
UUID=f34150e6-6d37-448c-b81f-69ecdcb13ed5 swap swap defaults 0 0Activate swap:
[root@lab ~]# swapon -aswapon -a is silent on success, so confirm the new swap size with
free -m:
[root@lab ~]# free -m
total used free shared buff/cache available
Mem: 3781 164 3237 8 378 3388
Swap: 511 0 511Grow the root filesystem
If you have not already run partprobe, do so before growing the
filesystem:
[root@lab ~]# partprobe /dev/sdadf still reports the pre-resize size until ext4 is grown online:
[root@lab ~]# df -h /dev/sda2
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 9.8G 1.3G 8.1G 14% /Run resize2fs on /dev/sda2:
[root@lab ~]# resize2fs /dev/sda2
resize2fs 1.44.3 (10-July-2018)
Filesystem at /dev/sda2 is mounted on /; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 2
The filesystem on /dev/sda2 is now 2883584 (4k) blocks long.Confirm the enlarged root partition:
[root@lab ~]# df -h /dev/sda2
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 11G 1.3G 9.0G 12% /Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
df unchanged after parted/fdisk |
Filesystem not grown yet | Run resize2fs (ext4) or xfs_growfs (XFS) on the mount |
| parted warns kernel still uses old partitions | Root partition was live-edited | Choose Ignore and finish resize2fs; do not reboot mid-session |
resize2fs errors on XFS |
Wrong tool for filesystem type | Use xfs_growfs / instead of resize2fs |
| No room to extend | Partition is not last, or no unallocated space | Expand the virtual disk first; remove or move trailing partitions |
| Swap missing after reboot | /etc/fstab still has old UUID |
Update UUID with blkid after mkswap |
partprobe fails on busy disk |
Partition in use | Complete filesystem grow online; schedule reboot only after swap is restored |
Summary
Extending a non-LVM root partition in Linux is a two-layer change.
First the partition table must expose more sectors to root. Then the
filesystem must grow into that space with resize2fs or xfs_growfs.
Both parted and fdisk change the table by deleting and recreating
the root entry with the same start sector and a larger end boundary.
That preserves ext4 data as long as you do not reformat.
When swap is the last partition, remove it temporarily, grow root into trailing free space, and recreate swap at the end of the disk. Back up first, never change the root start sector, and finish with a filesystem grow before you treat the resize as complete.
For LVM-based systems, prefer extending the logical volume instead of editing primary partition boundaries.
References
- GNU Parted manual — resize and
mkpartsyntax - fdisk(8) — MBR/GPT partition editing
- resize2fs(8) — grow ext2/ext3/ext4 online
- xfs_growfs(8) — grow a mounted XFS filesystem

