I found that TRIM was not working on an encrypted Arch Linux system.
The first check was:
sudo fstrim -v /
This returned:
fstrim: /: the discard operation is not supported
Next I checked discard support through the storage stack:
lsblk -D
The relevant part of the output was:
nvme0n1 0 512B 2T 0
├─nvme0n1p1 0 512B 2T 0
├─nvme0n1p2 0 512B 2T 0
└─nvme0n1p3 0 512B 2T 0
└─archlinux 0 0B 0B 0
The NVMe drive and partition support discard, but the encrypted archlinux mapping reports 0B, so discard is not being passed through the encrypted mapping.
I then checked which device contains the root filesystem:
findmnt -no SOURCE /
This returned:
/dev/mapper/archlinux[/@]
Next I checked discard support through the storage stack:
lsblk -D
The relevant part of the output was:
NAME DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
nvme0n1 0 512B 2T 0
├─nvme0n1p1 0 512B 2T 0
├─nvme0n1p2 0 512B 2T 0
└─nvme0n1p3 0 512B 2T 0
└─archlinux 0 0B 0B 0
The NVMe device and its partition support discard, but the encrypted archlinux mapping reports 0B, so discard is being blocked at the encrypted mapping.
Next I checked which device contains the root filesystem:
findmnt -no SOURCE /
This returned:
/dev/mapper/archlinux[/@]
This shows that the root filesystem is on the archlinux device-mapper mapping, with @ as the Btrfs subvolume.
Next I checked the encrypted mapping:
sudo cryptsetup status archlinux
This returned:
/dev/mapper/archlinux is active and is in use.
type: LUKS2
cipher: aes-xts-plain64
keysize: 512 [bits]
key location: keyring
device: /dev/nvme0n1p3
sector size: 512 [bytes]
offset: 32768 [512-byte units] (16777216 [bytes])
size: 975165455 [512-byte units] (499284712960 [bytes])
mode: read/write
The important part here is that the mapping is using LUKS2.
The backing device is shown by cryptsetup status. On this system it is:
device: /dev/nvme0n1p3
So when inspecting the LUKS2 header, use that device rather than a hard-coded device name:
sudo cryptsetup luksDump /dev/nvme0n1p3 | grep -i Flags
Use the device reported by cryptsetup status on your own system.
On this system the check returned:
Flags: (no flags)
So there were no persistent LUKS2 flags set before enabling discard.
To enable persistent discard on the active LUKS2 mapping:
sudo cryptsetup --allow-discards --persistent refresh archlinux
This prompted for the LUKS passphrase:
Enter passphrase for /dev/nvme0n1p3:
Enter the passphrase used to unlock that encrypted volume.
After entering the passphrase, I checked the LUKS2 flags again:
sudo cryptsetup luksDump /dev/nvme0n1p3 | grep -i Flags
This now returned:
Flags: allow-discards
So the persistent allow-discards flag is now set on the LUKS2 volume.
With discard enabled through LUKS, I ran TRIM again:
sudo fstrim -v /
This time it succeeded:
/: 100.6 GiB (108015452160 bytes) trimmed
On this system the first successful trim took a few minutes to complete.
Finally, I enabled the weekly systemd TRIM timer:
sudo systemctl enable --now fstrim.timer
This returned:
Created symlink '/etc/systemd/system/timers.target.wants/fstrim.timer' → '/usr/lib/systemd/system/fstrim.timer'.
I then verified the timer:
sudo systemctl status fstrim.timer
The important parts of the output were:
Loaded: loaded (/usr/lib/systemd/system/fstrim.timer; enabled; preset: disabled)
Active: active (waiting)
Trigger: Mon 2026-08-31 01:32:52 BST; 6 days left
This confirms that the weekly TRIM timer is enabled and waiting for its next scheduled run.
As a final check, I ran:
lsblk -D
The relevant part now showed:
nvme0n1 0 512B 2T 0
├─nvme0n1p1 0 512B 2T 0
├─nvme0n1p2 0 512B 2T 0
└─nvme0n1p3 0 512B 2T 0
└─archlinux 0 512B 2T 0
The encrypted archlinux mapping now reports the same discard granularity and maximum discard size as the underlying NVMe device, confirming that discard is being passed through successfully.
A final cryptsetup status check also shows discard enabled on the active mapping:
sudo cryptsetup status archlinux
The relevant line is:
flags: discards
This confirms that discard is enabled on the currently active LUKS mapping as well as being stored persistently in the LUKS2 metadata.