How to Resize a LUKS Partition (Extend or Shrink) in Linux

Extend or shrink a LUKS2 ext4 volume on Linux: grow the partition first, run cryptsetup resize on the mapper, then resize2fs; for shrink, reverse the order with offline resize2fs and --size in 512-byte sectors.

Published

Updated

Read time 12 min read

Reviewed byDeepak Prasad

Extend or shrink a LUKS2 encrypted partition with cryptsetup and resize2fs

You encrypted a data partition with LUKS and now the volume is too small—or you reclaimed space and need to shrink it. LUKS does not bake the partition size into the header, so resizing is possible when you follow the right order:

  • Extend (outside → inside): partition/disk → LUKS mapper → filesystem
  • Shrink (inside → outside): filesystem → LUKS mapper → partition

This walkthrough uses LUKS2 with ext4:

  • Inspect a real secondary disk (/dev/sdc1, mapper secure_data) to read the stack
  • Run extend and shrink on a loop-file lab where growing and shrinking are safe to repeat

Related guides:

Tested on: Ubuntu 26.04 LTS (Resolute Raccoon); kernel 7.0.0-27-generic; cryptsetup 2.8.4.

IMPORTANT
This article covers resizing a secondary LUKS data partition you unlock with cryptsetup open—extend when free space follows the partition on the disk, or shrink with an offline filesystem check. It does not cover resizing the encrypted root volume your system boots from (initramfs, bootloader, and partition layout are a migration project) or removing encryption without restoring data elsewhere.

Quick reference: extend vs shrink order

Goal Order (outside → inside) Key commands
Extend Partition/disk → LUKS mapper → filesystem growpart or parted resizepartcryptsetup resizeresize2fs
Shrink Filesystem → LUKS mapper → partition umounte2fsck -fresize2fs SIZEcryptsetup resize --size SECTORSparted resizepart

LUKS sits between the partition and the filesystem. Wrong order causes:

  • Filesystem larger than the encrypted area (extend mistakes)
  • Truncated data (shrink mistakes)

What you need

  • Root or sudo on the host
  • cryptsetup, e2fsprogs, and parted (or growpart from cloud-guest-utils on Ubuntu)
  • A current data backup and a LUKS header backup before any shrink
  • The LUKS volume unmounted for shrink; extend can grow ext4 online only after the mapper and LUKS payload are already larger
  • Free unallocated space after the partition when you extend a physical disk (or a larger loop/image file in a lab)

On Fedora and other distributions:

  • Install the same packages locally
  • The cryptsetup resize workflow is not Ubuntu-specific

Inspect the LUKS stack before you resize

Before you resize, confirm:

  • Which block device is the LUKS container
  • Which mapper name is open
  • The size: field in 512-byte sectors

On the lab host, /dev/sdc1 holds the cluster demo volume secure_data. Open it and print the block layout:

bash
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT /dev/sdc
sudo cryptsetup open /dev/sdc1 secure_data

Then read the LUKS payload size in 512-byte sectors:

bash
sudo cryptsetup status secure_data

Sample output:

text
NAME                  SIZE TYPE  FSTYPE      MOUNTPOINT
sdc                     5G disk
└─sdc1                  5G part  crypto_LUKS
  └─secure_data         5G crypt ext4

/dev/mapper/secure_data is active.
  type:       LUKS2
  cipher:     aes-xts-plain64
  keysize:    512 bits
  device:     /dev/sdc1
  sector size: 512
  offset:     32768 sectors
  size:       10448896 sectors
  mode:       read/write

From cryptsetup status:

  • device: — LUKS container (/dev/sdc1)
  • offset: — payload offset inside the LUKS container, shown in sectors/512-byte units in cryptsetup status; add this to the partition start when calculating the absolute disk end sector
  • size: — encrypted payload in 512-byte sectors (use with cryptsetup resize --size when shrinking)
  • For parted resizepart, the end sector is absolute on the disk: partition_start + offset + size - 1

Close the mapper when you finish inspecting: sudo cryptsetup close secure_data.

WARNING
Shrinking is irreversible if you truncate the filesystem or LUKS area too far. Work on a copy or VM first when the data matters.

If LUKS sits on an LVM logical volume inside the mapper, see LVM on LUKS — the order includes pvresize, not just lvextend / lvreduce.


Extend a LUKS partition

Extending needs free space after the partition on the same disk (or a larger backing image).

  • Loop lab: 2 GiB image → 3 GiB (safe to repeat)
  • Physical disk: sudo growpart /dev/sdc 1 when unallocated space follows sdc1

Step 1: Grow the partition or backing image

For a loop-file lab, grow the file, refresh the kernel’s view of the loop size, fix the GPT if needed, then grow partition 1:

bash
IMG=/var/tmp/luks-resize-lab.img
LOOP=/dev/loop24

truncate -s 3G "$IMG"
sudo losetup -c "$LOOP"
sudo sgdisk -e "$LOOP"
sudo partprobe "$LOOP"
sudo parted -s "$LOOP" resizepart 1 100%

Loop-file gotchas after truncate:

  • losetup -c — refresh kernel loop size (without it, cryptsetup resize has nothing to grow into)
  • sgdisk -e — move backup GPT to the end of a grown image file
  • partprobe — pick up the resized partition table

On a real disk with space after partition 1:

bash
sudo growpart /dev/sdc 1

Check that the partition picked up the new space:

bash
lsblk -o NAME,SIZE,TYPE,FSTYPE "$LOOP"

Sample output:

text
NAME            SIZE TYPE  FSTYPE
loop24            3G loop
└─loop24p1        3G part  crypto_LUKS
  └─resize_demo   2G crypt ext4

loop24p1 is 3 G but the mapper is still 2 G—the next step grows the LUKS payload.

Step 2: Resize the LUKS mapper

With the mapper already open (resize_demo in the lab), grow the LUKS encrypted area to fill the partition. Omit --size so cryptsetup uses the maximum allowed by the backing device:

bash
sudo cryptsetup resize resize_demo

A successful grow prints nothing. Confirm the new sector count:

bash
sudo cryptsetup status resize_demo | grep -E 'size:|offset:'

Sample output:

text
offset:  32768 [512-byte units] (16777216 [bytes])
  size:    6256607 [512-byte units] (3203382784 [bytes])

6256607 sectors × 512 bytes ≈ 2.98 GiB — the LUKS payload now matches the grown 3 G partition (minus header offset).

HINT
cryptsetup resize expects --size in 512-byte sectors when you pass a value. Suffixes like 512M are not valid for --size: cryptsetup: invalid numeric value is the error you get. Do not confuse --size with --device-size — the latter accepts unit suffixes (M, G, MiB), but this guide uses --size because it matches the cryptsetup status sector output. Omit --size to grow to the backing device maximum, or pass an explicit sector count when shrinking.

Step 3: Grow ext4 on the mapper

With the mapper still open, grow the filesystem. ext4 can expand online while mounted:

bash
sudo resize2fs /dev/mapper/resize_demo

Sample output:

text
resize2fs 1.47.2 (1-Jan-2025)
Filesystem at /dev/mapper/resize_demo is mounted on /mnt/resize-demo; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/mapper/resize_demo is now 782075 (4k) blocks long.

Check usable space at the mount point:

bash
df -h /mnt/resize-demo

Sample output:

text
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/resize_demo  2.9G  532K  2.8G   1% /mnt/resize-demo

Extend order in one line: partition → cryptsetup resizeresize2fs. For related flags and operations, see the cryptsetup command cheatsheet.


Shrink a LUKS partition

Shrinking is offline work:

  1. umount
  2. Shrink filesystem (resize2fs)
  3. Shrink LUKS payload (cryptsetup resize --size)
  4. Shrink partition (parted resizepart)

Target sizes:

  • Loop lab: 1800 M on the ~2.9 G filesystem after the extend demo
  • 5 G secure_data: pick a target smaller than the current filesystem size, but larger than the data currently used, with a safety margin

Step 1: Unmount and run a full fsck

Take the filesystem offline, then force a full check before shrinking. On production disks, answer repair prompts yourself:

bash
sudo umount /mnt/resize-demo
sudo e2fsck -f /dev/mapper/resize_demo

In a disposable lab (or a script where you accept automatic repairs), add -y:

bash
sudo e2fsck -fy /dev/mapper/resize_demo

Sample output:

text
e2fsck 1.47.2 (1-Jan-2025)
Pass 1: Checking inodes, blocks, and sizes
...
/dev/mapper/resize_demo: 13/195072 files (0.0% non-contiguous), 22095/782075 blocks

Do not use -y on real data unless you are sure every automatic repair is acceptable.

Step 2: Shrink ext4 to the target size

Shrink the filesystem offline to 1800 M (smaller than the current ~2.9 G lab size):

bash
sudo resize2fs /dev/mapper/resize_demo 1800M

Sample output:

text
resize2fs 1.47.2 (1-Jan-2025)
Resizing the filesystem on /dev/mapper/resize_demo to 460800 (4k) blocks.
The filesystem on /dev/mapper/resize_demo is now 460800 (4k) blocks long.

If the filesystem is still mounted, ext4 stops you. Remount and try shrinking again to see the error:

bash
sudo mount /dev/mapper/resize_demo /mnt/resize-demo
sudo resize2fs /dev/mapper/resize_demo 1500M

Sample output:

text
resize2fs 1.47.2 (1-Jan-2025)
resize2fs: On-line shrinking not supported
Filesystem at /dev/mapper/resize_demo is mounted on /mnt/resize-demo; on-line resizing required

Unmount first, then rerun resize2fs.

Step 3: Shrink the LUKS mapper with --size in sectors

Pass a sector count slightly larger than the shrunk filesystem:

  • Lab value: 3775000 sectors (512-byte units)
  • Read cryptsetup status after resize2fs if you are unsure

Unmount (if needed), then shrink the LUKS payload:

bash
sudo umount /mnt/resize-demo
sudo cryptsetup resize resize_demo --size 3775000

Suffixes like 512M are not valid for --size. This fails immediately:

bash
sudo cryptsetup resize resize_demo --size 512M

Sample output:

text
cryptsetup: invalid numeric value

Always use a plain integer sector count with --size. Verify the LUKS payload shrank:

bash
sudo cryptsetup status resize_demo | grep 'size:'

Sample output:

text
size:    3775000 [512-byte units] (1932800000 [bytes])

Step 4: Shrink the partition

parted resizepart expects an absolute end sector on the disk—not a value relative to the partition start. Read the partition start sector first:

bash
sudo parted /dev/loop24 unit s print

Sample output:

text
Number  Start   End       Size      File system  Name
 1      2048s   6291422s  6289375s               primary

Calculate the new absolute end sector:

text
new_partition_end = partition_start + LUKS_offset + LUKS_size - 1

For this lab (partition_start 2048, LUKS_offset 32768, LUKS_size 3775000):

text
2048 + 32768 + 3775000 - 1 = 3809815

Shrink partition 1 to that absolute sector:

bash
sudo parted /dev/loop24 unit s resizepart 1 3809815s

parted asks Yes/No? when shrinking — answer Yes. Then verify the partition is still large enough for the LUKS header and payload:

bash
lsblk -o NAME,SIZE,TYPE,FSTYPE /dev/loop24
sudo cryptsetup status resize_demo | grep -E 'size:|offset:'

Check:

  • partition_length (in sectors) ≥ LUKS_offset + LUKS_size
  • Equivalently, the partition end sector you passed is ≥ partition_start + LUKS_offset + LUKS_size - 1

LVM on LUKS extend and shrink order

Stack: partition → LUKS → LVM → filesystem

The LUKS mapper is the LVM physical volume. You must resize the PV with pvresize whenever the mapper size changes.

Goal Correct order for partition → LUKS → LVM → filesystem
Extend Grow partition (if needed) → cryptsetup resizepvresize /dev/mapper/namelvextend → grow filesystem (resize2fs, xfs_growfs, etc.)
Shrink Shrink filesystem → lvreducepvresize --setphysicalvolumesize SIZE /dev/mapper/namecryptsetup resize --size SECTORS → shrink partition
WARNING
Do not run cryptsetup resize --size before reducing the LVM PV. That can truncate the physical volume while logical volumes still expect extents near the end of the mapper.

LVM cautions:

  • Shrink the filesystem before lvreduce — reducing the LV first can destroy data
  • If pvresize --setphysicalvolumesize refuses because extents sit near the end of the PV, move or remove those extents first; do not force the LUKS or partition layer smaller until LVM reports the PV fits the target size
  • On another host, open and unlock LUKS before resizing LVM or the filesystem

Order-of-operations pitfalls

Mistake What goes wrong Fix
resize2fs before growing partition/LUKS Filesystem has no room to grow Extend partition/image first, then cryptsetup resize, then resize2fs
cryptsetup resize before shrinking filesystem LUKS area smaller than ext4 superblock Shrink ext4 offline first, then cryptsetup resize --size
Shrink partition before LUKS/filesystem Truncates encrypted data Shrink filesystem and LUKS, then partition last
Wrong parted end sector (LUKS offset only) Partition ends inside the LUKS area Use absolute end: partition_start + LUKS_offset + LUKS_size - 1
cryptsetup resize --size before lvreduce/pvresize Truncates LVM PV while LVs still use extents Shrink filesystem → lvreducepvresize --setphysicalvolumesize → then LUKS and partition
Extend LUKS without pvresize lvextend has no free PV space Run pvresize /dev/mapper/name after cryptsetup resize
cryptsetup resize --size 512M invalid numeric value for --size Use --size SECTORS (512-byte sectors), not --device-size syntax on --size
Shrink ext4 while mounted On-line shrinking not supported umount, then resize2fs
Skip e2fsck -f before shrink resize2fs may refuse or corrupt Always force-check offline before shrinking
Filesystem larger than LUKS size I/O errors, mount failures Grow LUKS with cryptsetup resize before resize2fs when extending
truncate on loop image without losetup -c Partition grows but LUKS cannot extend Run losetup -c (or detach and reattach) after growing the image file

btrfs and XFS notes

This guide focuses on ext4 (offline shrink is supported). Other filesystems:

Filesystem Grow Shrink
ext4 resize2fs (online after LUKS grow) resize2fs SIZE offline only
btrfs btrfs filesystem resize btrfs filesystem resize with negative size (online shrink possible)
XFS xfs_growfs mountpoint No shrink—backup, recreate smaller LUKS, restore

Non-ext4 notes:

  • XFS on LUKS — no in-place shrink; migrate data, recreate smaller LUKS, restore
  • btrfs on LUKS — shrink btrfs first, then cryptsetup resize --size, then the partition

Troubleshooting

Symptom Likely cause Fix
On-line shrinking not supported ext4 shrink attempted on a mounted filesystem Unmount (or boot rescue media for root), run e2fsck -f, then resize2fs /dev/mapper/name TARGET
invalid numeric value from cryptsetup resize Suffix (512M, 3G) passed to --size (sectors only) Read size: from cryptsetup status, or use --device-size with units—not on --size
Filesystem bigger than LUKS after extend resize2fs ran before cryptsetup resize Grow the mapper first: sudo cryptsetup resize resize_demo, then sudo resize2fs /dev/mapper/resize_demo
cryptsetup resize fails or hangs with no output Backing partition still at old size (common on loop images after truncate) losetup -c, sgdisk -e, partprobe, then parted resizepart before cryptsetup resize
resize2fs: requested size larger than containing partition Target shrink size exceeds current filesystem Pick a target smaller than current filesystem size but larger than used data, with margin
Data past the new end after shrink Partition shortened before filesystem and LUKS payload shrank Restore from backup or LUKS header backup if available; do not mount and write

References


Summary

  • Extend (plain partition): grow partition/image → cryptsetup resizeresize2fs /dev/mapper/name
  • Shrink (plain partition): umount → e2fsck -fresize2fs TARGETcryptsetup resize --size SECTORSparted resizepart with absolute end partition_start + LUKS_offset + LUKS_size - 1
  • LVM inside LUKS: add pvresize on extend and lvreduce + pvresize --setphysicalvolumesize before shrinking LUKS
  • Back up data and the LUKS header before any shrink; wrong ordering causes permanent loss

Frequently Asked Questions

1. Can I resize a LUKS partition while it is mounted?

You can extend ext4 online after cryptsetup resize, but shrinking requires umount. resize2fs refuses on-line shrinking on ext4, so plan downtime for any shrink workflow.

2. Does cryptsetup resize change the filesystem size automatically?

No. cryptsetup resize only changes the encrypted mapper and LUKS payload area. You must run resize2fs (ext4), btrfs filesystem resize, or xfs_growfs separately on /dev/mapper/name.

3. What unit does cryptsetup resize --size expect?

Sector count using 512-byte sectors, not MiB/GiB suffixes. Passing --size 512M produces cryptsetup: invalid numeric value; calculate sectors or read the size field from cryptsetup status.

4. Is shrinking a LUKS partition safe without a backup?

No. A wrong order (LV before filesystem, or partition before LUKS) can leave the volume unrecoverable. Back up data and capture a LUKS header backup before any shrink.

5. Do I need LVM to resize LUKS?

No for a plain partition. If LVM sits inside the LUKS mapper, extend needs pvresize after cryptsetup resize and before lvextend; shrink needs filesystem and lvreduce/pvresize before cryptsetup resize --size.

6. Does this guide decrypt or remove LUKS encryption?

No. Resizing keeps encryption intact. Removing LUKS (luksRemove or luksFormat on a populated volume) is a separate destructive operation—back up first and treat it as data loss if you only wanted more free space.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …