I’m running Virtualmin 8.1 on Ubuntu 24.04 (Hetzner VPS) with /home on a separate ext4 volume. I configured disk quotas using the native ext4 quota feature (via tune2fs -O quota) instead of the traditional aquota.user/aquota.group files.
Everything works correctly:
quotaon -p /home → user and group quota is on
repquota -a → shows correct usage and limits for all virtual server users
However, Check Disk Quotas in Virtualmin always reports:
quotacheck: Unknown quota format: /home
The root cause is that Webmin’s quota module runs quotacheck -u -g without specifying the format. When using native ext4 quota, there are no aquota.* files on disk, so quotacheck cannot auto-detect the format and fails.
Suggested fix: before running quotacheck, detect whether the filesystem has native quota enabled in the superblock (e.g. tune2fs -l <device> | grep -q quota) and skip quotacheck entirely in that case — it’s not needed for native ext4 quota.
We’d also like to ask a broader question: is there any reason why using native ext4 quota (via tune2fs -O quota) would be considered a bad approach for a Virtualmin server? We chose it because on Ubuntu 24.04 the traditional method with aquota.* files failed with the same “Unknown quota format” error, and native ext4 quota seemed like the modern and recommended way. If there are known issues or limitations with this approach in the context of Virtualmin, we’d appreciate the heads-up.
I have no idea what “native quotas” means. I mean, there’s always been native support for quotas in ext4, and we’ve always used the native quota tools. We’re certainly not inventing our own quota tools.
Can you point to documentation about what is new about quotas on a new Ubuntu ext4 filesystem that would be incompatible with the way it’s always been done?
Thanks for the response, that’s a fair point. Let me clarify.
The difference I’m referring to is how quota data is stored on the filesystem:
Traditional method quota data is stored in files aquota.user and aquota.group in the root of the filesystem, with usrquota,grpquota mount options in /etc/fstab.
What I have is quota data is stored in special inodes (inode 3 and 4) inside the ext4 superblock itself, enabled via:
bash
tune2fs -O quota /dev/sdX
No aquota.* files are created, and no extra mount options are needed in /etc/fstab.
This can be seen in the output of:
bash
tune2fs -l /dev/sdX | grep -I quota
Which on the system returns:
Filesystem features: ... quota ...
User quota inode: 3
Group quota inode: 4
Quota is working fine. The quotaon -p /home reports is on and repquota -a shows correct data for all users. The only issue is that quotacheck -u -g (called by Webmin during “Check Disk Quotas”) cannot auto-detect this format when no aquota.* files exist, and reports Unknown quota format.
Happy to provide any additional info that would help track it.
TL;DR native ext4 quota solved the by-id device path problem, and repquota bridged the gap where Dovecot fell short.
Let me write the full story, which might actually be useful context for others too.
Why I switched from aquota files to superblock-based quota:
The traditional method stored quota data in aquota.user and aquota.group files in /home. I wanted to enable quota reporting over IMAP so users can see their mailbox limits in their mail client. Dovecot was trying to read quota limits via quotactl(Q_GETQUOTA, /dev/sdb) but was failing with:
quota-fs: quotactl(Q_GETQUOTA, /dev/sdb) failed: No such file or directory
The root cause was that my volume is mounted by persistent id (/dev/disk/by-id/<device-by-id>) rather than directly as /dev/sdb. This caused quotactl to fail to locate the device correctly in Dovecot’s process context (even though /dev/sdb physically existed).
Switching to superblock-based quota (tune2fs -O quota) moves quota metadata directly into the filesystem superblock - no external files, kernel manages consistency internally. It’s the more modern approach and solved the device path issue.
However it turned out that Dovecot 2.3.21 doesn’t handle native ext4 quota via quotactl correctly either (returning EINVAL). So I ultimately switched to the maildir backend with a script generating limits from repquota. The native ext4 quota was kept in place because it works better for the system overall, and repquota works with it without any issues.
lol. Sounds like the best kept secret in Linux. But, we’re not opposed to supporting it. I can’t make an estimate for how long it’ll take, as I don’t yet understand it, but it’s probably not a huge undertaking.