Your thin pool hit 100% data usage, writes to every thin LV in the pool started failing, and the auto-extend you thought was protecting you never fired. Or you are reading this before that happens, auditing a pool that has been “protected” for months without anyone ever confirming the mechanism works.
The most common root cause is a one-line surprise in /etc/lvm/lvm.conf: the default value of thin_pool_autoextend_threshold is 100, and a threshold of 100 does not mean “extend when the pool is full”. It means auto-extend is disabled. The commented-out line # thin_pool_autoextend_threshold = 100 in the shipped config looks like a sensible default. It is the off switch.
Even with the threshold set correctly, auto-extend still fails silently if dmeventd is not running, if the pool is not registered for monitoring, or if the volume group has no free extents to extend into. No error is surfaced to applications in any of these cases. The first symptom is the pool filling up.
What this means
Thin pool auto-extend is not a kernel feature. It is a userspace policy executed by dmeventd (the device-mapper event daemon, usually managed as lvm2-monitor.service). The chain that has to work end to end is:
thin_pool_autoextend_thresholdin/etc/lvm/lvm.confmust be below 100 (values below 50 are treated as 50).thin_pool_autoextend_percentmust be greater than 0 (it controls how much the pool grows per event, as a percentage of current size).- dmeventd must be running.
- The thin pool must be registered for monitoring with dmeventd (
seg_monitorstate). - The VG must have free extents when the event fires.
If any link breaks, nothing happens. dmeventd does not page you. A failed extend is retried internally with increasing delays (up to roughly 42 minutes between attempts), but if the VG is full it will simply never succeed.
flowchart TD
A[Pool data usage crosses threshold] --> B{threshold < 100 in lvm.conf?}
B -- "No: default is 100" --> X1[Auto-extend disabled. Nothing fires.]
B -- Yes --> C{dmeventd running?}
C -- No --> X2[No event handling. Silent.]
C -- Yes --> D{Pool monitored? seg_monitor}
D -- No --> X3[dmeventd not watching this pool. Silent.]
D -- Yes --> E{VG has free extents?}
E -- No --> X4[Extend attempted, fails, retried. Silent.]
E -- Yes --> F[Pool extended by autoextend_percent]Common causes
| Cause | What it looks like | First thing to check |
|---|---|---|
| Threshold still at default 100 | Pool fills to 100% with no extend ever attempted | lvmconfig activation/thin_pool_autoextend_threshold |
| dmeventd not running | Threshold is correct, still no extend events | systemctl is-active lvm2-monitor.service |
| Pool not monitored | dmeventd runs but ignores this pool | lvs -o+seg_monitor vg/pool |
thin_pool_autoextend_percent is 0 | Threshold crossing logged, pool size never changes | lvmconfig activation/thin_pool_autoextend_percent |
| VG out of free extents | Extend events fire and fail, pool keeps filling | vgs -o vg_name,vg_free |
| Config edited but service never restarted | New values in file, old behavior in production | Restart lvm2-monitor and verify with a forced event |
| Containerized LVM (e.g. lvm-localpv) | Auto-extend never works inside the container | dmeventd in the container cannot manage host pools |
Quick checks
All read-only and safe to run during an incident.
# 1. Effective auto-extend configuration (what LVM is actually using)
lvmconfig activation/thin_pool_autoextend_threshold activation/thin_pool_autoextend_percent
# 2. Is dmeventd running?
systemctl is-active lvm2-monitor.service
pgrep -x dmeventd
# 3. Is the pool registered for monitoring?
# Look for "monitored" in the output. "not monitored" means dmeventd ignores it.
lvs -o lv_name,vg_name,seg_monitor vg/thinpool
# 4. Current pool usage, data and metadata
lvs -o lv_name,vg_name,data_percent,metadata_percent,lv_size vg/thinpool
# 5. Does the VG have room to extend into?
vgs -o vg_name,vg_size,vg_free
# 6. Pool health flag (position 9 of lv_attr: D = out of data space, F = failed)
lvs -o lv_name,vg_name,lv_attr vg/thinpool
# 7. Raw pool status from kernel memory (works even if lvs hangs on a sick pool)
dmsetup status vg-thinpool-tpool 2>/dev/null || dmsetup status --target thin-pool
Two notes. First, prefer lvmconfig over grep on lvm.conf: it shows the merged effective value, which is what matters when a commented default is in play. Second, check 7 exists because lvs takes LVM metadata locks and performs I/O. If the pool is already full and the system is sick, lvs can hang while dmsetup status still answers, since it reads from kernel memory.
How to diagnose it
Confirm the symptom precisely. Is the pool actually full (data_percent at or near 100, health flag
D), or is auto-extend merely suspected broken?lvs -o lv_name,data_percent,lv_attr vg/thinpoolanswers this.Read the effective threshold.
lvmconfig activation/thin_pool_autoextend_threshold. If it prints 100, you have found it: auto-extend was never enabled. This is the most frequent cause, because every major distribution (RHEL 7 through 9, Ubuntu, Debian, Arch) ships 100 as the default. Since lvm2-2.02.152, LVM prints a warning when you create thin LVs with auto-extend disabled, but pools created before that, or via tooling that suppresses output, never surfaced it.Check dmeventd. If the threshold is sane, verify
lvm2-monitor.serviceis active. A pool with a correct threshold and no dmeventd behaves identically to threshold 100: nothing happens. The service state at boot is what matters; if it was started late or failed once, the pool may never have been registered.Check the monitoring registration.
lvs -o+seg_monitor vg/thinpool. dmeventd only acts on pools it is monitoring. A pool that reports “not monitored” needslvchange --monitor y vg/thinpool.Check VG headroom.
vgs -o vg_free. Auto-extend consumes VG extents at each event, roughlycurrent_pool_size * autoextend_percent / 100per cycle. If the VG has been full for weeks, every event has been failing silently in the background.Prove it end to end. Do not close the incident on a config edit. Either wait for organic growth to cross the threshold, or temporarily lower the threshold below current usage and watch
lvs -o lv_sizeand the journal for dmeventd activity until the pool extends. Restore the production threshold afterwards.
Metrics and signals to monitor
| Signal | Why it matters | Warning sign |
|---|---|---|
| Thin pool data_percent | The countdown to write failure across all thin LVs in the pool | Above 85% |
| Thin pool metadata_percent | Separate exhaustion domain, can corrupt the pool at 100% | Above 75% |
| seg_monitor state | Tells you whether dmeventd is watching the pool at all | “not monitored” on a production pool |
| dmeventd process / lvm2-monitor.service | No daemon, no auto-extend, regardless of config | Service inactive on any host with thin pools |
| Effective threshold and percent (config audit) | Threshold 100 reads as configured but means disabled | Any pool on a host with threshold >= 100 |
| VG free space | Auto-extend’s fuel; zero free extents means events fire and fail | Below what two extend cycles would consume |
| Pool size over time | The only proof auto-extend has ever actually worked | Threshold crossed repeatedly with no size change |
Fixes
Fix the disabled default
Edit /etc/lvm/lvm.conf:
activation {
thin_pool_autoextend_threshold = 80
thin_pool_autoextend_percent = 20
}
A threshold of 70-80 leaves room for write bursts between the event and the extend completing. The percent controls growth per event; the default is 20, but it must be greater than 0 and large enough that one event buys meaningful runway. Beware: an over-aggressive percent on a nearly-full VG can let one extend consume the last of your VG headroom.
Restore dmeventd
# Enable and start the event daemon
systemctl enable --now lvm2-monitor.service
# Register an existing pool for monitoring if seg_monitor says otherwise
lvchange --monitor y vg/thinpool
After changing lvm.conf, restart the service so dmeventd picks up the new thresholds. On RHEL-family systems the unit is lvm2-monitor.service; other distributions may wire dmeventd differently, so verify with pgrep -x dmeventd rather than assuming.
Feed the VG
If VG free space is the blocker, no LVM config change fixes auto-extend. You need new capacity (pvcreate + vgextend on a new device) or you need to free space inside the pool: delete stale thin snapshots, and run fstrim on thin LV filesystems so discarded blocks return to the pool. Without discard, deleted data never frees pool space. See the related guide on extending LVs when the VG is full.
Emergency: pool already at 100%
If the pool is full right now, extend it manually. This is safe online:
# Manual extend of the pool itself (not the individual thin LVs)
lvextend -L +20G vg/thinpool
If the VG is also full, adding a PV comes first. Check the pool’s error policy: by default LVM uses error_if_no_space, so writes fail immediately when the pool is full. If the pool was created or changed to queue_if_no_space, writes instead queue until the no-space timeout (60 seconds by default) and then error, which looks like a hung system. In either state, lvs can become unresponsive; use dmsetup status --target thin-pool for diagnosis.
Containerized LVM
If your LVM is managed from inside a container (for example OpenEBS lvm-localpv), dmeventd inside the container cannot act on the host’s device-mapper events, and auto-extend will not work from there. Run monitoring and dmeventd on the host, or handle extension from your platform layer.
Prevention
- Audit the threshold everywhere. Add “effective
thin_pool_autoextend_threshold< 100 andthin_pool_autoextend_percent> 0” to your configuration management as an enforced assertion, not a documentation line. Treat threshold 100 on a host with thin pools as a finding. - Monitor dmeventd as a first-class service. It is the safety net for thin pools, RAID event handling, and snapshot overflow. Alert when it is not running on any host with thin provisioning.
- Alert on “threshold crossed, size unchanged”. Track pool size alongside data_percent. Data crossing 80% with no subsequent size increase is the auto-extend failure signature, and it is detectable long before 100%.
- Keep VG headroom for at least two extend cycles. Auto-extend is only as good as the free extents behind it. Track VG free as a separate capacity dimension from both filesystem usage and pool usage.
- Prove the mechanism once per pool. After any change, force or observe one real extend event. Most teams first test auto-extend during the incident it was supposed to prevent.
- Do not rely on
df. A thin LV’s filesystem can show 50% used while the pool underneath is at 98%. These are independent failure domains and need independent alerts.
How Netdata helps
- Per-second disk and device-mapper metrics let you see pool-adjacent I/O behavior (latency climbing as the pool approaches full from reclaim overhead) before writes start failing, rather than after.
- Correlating block-device saturation with LVM layer state shortens the “is it the pool or the disk” question that opens every thin pool incident.
- Service and process monitoring catches the dmeventd gap directly:
lvm2-monitor.servicegoing inactive on a host with thin pools is itself an alertable event, days before the pool fills. - Filesystem usage vs. block device trends side by side makes the classic thin-provisioning blind spot visible: flat
dfnumbers against a steadily filling backing device. - Historical trend retention is what LVM itself lacks. LVM commands report current state only; runway estimation for data_percent and VG free requires a time series, and that trend is also how you prove an extend event actually fired.
- ML anomaly detection on I/O latency flags the subtle pre-failure degradation (allocator strain near pool capacity) that static thresholds on utilization alone miss.
Related guides
- LVM cannot extend a logical volume: adding a PV when the VG is full
- LVM filesystem full while the volume group has space: the resize step everyone forgets
- How LVM actually works in production: a mental model for operators
- LVM Insufficient free extents: the volume group is out of space
- LVM monitoring checklist: the signals every production volume manager needs
- LVM monitoring maturity model: from survival to expert
- LVM has free space but striped or mirrored allocation still fails
- LVM volume group running low on free space: vg_free and runway estimation






