Feature Flags
ZFS on-disk formats were originally versioned with a single number, which increased whenever the format changed. The numbered approach was suitable when development of ZFS was driven by a single organisation.
For distributed development of OpenZFS, version numbering was unsuitable. Any change to the number would have required agreement, across all implementations, of each change to the on-disk format.
OpenZFS feature flags – an alternative to traditional version numbering – allow a uniquely named pool property for each change to the on-disk format. This approach supports:
format changes that are independent
format changes that depend on each other.
Feature states
Each feature is exposed as a pool property named feature@<short-name> and
is in one of three states:
disabledThe on-disk format change has not been made and will not be, unless an administrator enables it.
enabledMarked as enabled, but the on-disk format change has not happened yet. The pool can still be imported by software that does not know the feature — until something triggers the change, which may happen at any time and moves the feature to
active.activeThe format change is in effect. Software must support the feature to import the pool read-write.
zpool get all pool | grep feature@
zpool get feature@large_blocks pool
Features cannot be disabled once enabled. Some can return from active
to enabled when whatever used them is freed — for example
block_cloning once the last cloned block is gone — but that is
feature-specific.
Enabling a feature automatically enables anything it depends on.
Read-only compatibility
Some format changes do not prevent other software from reading the pool. If every unsupported feature on a pool is read-only compatible, the pool can still be imported read-only:
zpool import -o readonly=on pool
For each unsupported feature on an imported pool, the property
unsupported@<feature-name> explains why the import was allowed:
inactive (the feature is only enabled, so the format is still
compatible) or readonly (it is read-only compatible and the pool was
imported read-only).
Compatibility
Where all features that are used by a pool are supported by multiple implementations of OpenZFS, the on-disk format is portable across those implementations.
Features that are exclusive when enabled should be periodically ported to all distributions.
Compatibility feature sets
The compatibility pool property pins a pool to a named on-disk format, so
it stays importable somewhere else — an older release, another OS, or a
bootloader.
off(default)No restriction; any feature may be enabled.
legacyNo features may be enabled at all — neither by
zpool upgradenor by settingfeature@…=enabled, and the pool cannot be upgraded to a newer on-disk version. A deliberate safety catch.file[,file…]One or more feature-set files. Only features present in all of the listed files may be enabled.
zpool create -o compatibility=grub2-2.12 bpool ...
zpool set compatibility=openzfs-2.1-linux tank
zpool get compatibility tank
Names are resolved relative to /etc/zfs/compatibility.d (local, takes
precedence) or /usr/share/zfs/compatibility.d (shipped by the
distribution), or given as absolute paths. The shipped sets cover OpenZFS
releases per platform (openzfs-2.1-linux, openzfs-2.2,
openzfs-2.3, openzfs-2.4, openzfs-2.0-freebsd…), older ZoL and
FreeBSD versions, GRUB (grub2-2.06, grub2-2.12), and yearly baselines
(compat-2018 … compat-2021).
ls /usr/share/zfs/compatibility.d/
Two practical uses dominate: a boot pool restricted to what the
bootloader understands, and a pool that must remain importable on an older
system. Setting compatibility also stops zpool status from nagging
about disabled features that are outside the chosen set.
Upgrading a pool
zpool upgrade # list pools with features not yet enabled
zpool upgrade -v # what this build supports
zpool upgrade pool # enable them on one pool
zpool upgrade -a # ...on every pool
zpool upgrade enables all supported features, subject to
compatibility: if a feature set is in force only features in that set are
enabled, and with legacy nothing happens at all.
Warning
Upgrading is one-way. Features cannot be disabled afterwards. Once
enabled features become active, the pool is no longer importable by
software that does not support them — which includes an older kernel you
might need to boot back into, a rescue USB stick, and the bootloader on a
root pool.
Upgrade deliberately, not reflexively because zpool status suggested
it. A pool that is not upgraded keeps working; it just does not offer the
newer features.
Note that zpool status reporting “some supported features are not
enabled” is informational. On a root or boot pool in particular, check what
your bootloader supports first — see the
Root on ZFS guides.
zfs upgrade is a different thing
Datasets carry their own on-disk version, independent of the pool’s features.
zfs upgrade # file systems not at the latest version
zfs upgrade -v # versions this build supports
zfs upgrade -r pool/data # upgrade a subtree
zfs upgrade -a # everything
The same one-way warning applies, with an extra consequence: after upgrading,
zfs send streams generated from new snapshots of those file systems
cannot be received by older ZFS versions either. If you replicate to an older
system, that will break the replication, not just the local mount.
Reference materials
ZFS Feature Flags (Christopher Siden, 2012-01, in the Internet Archive Wayback Machine) in particular: “… Legacy version numbers still exist for pool versions 1-28 …”.
zpool-features(7) man page - OpenZFS
zpool-features (5) – illumos
Feature flags implementation per OS
| Feature Flag | Read-Only Compatible | OpenZFS (Linux, FreeBSD 13+) | FreeBSD pre OpenZFS | Illumos | Joyent | NetBSD | Nexenta | OmniOS CE | OpenZFS on OS X | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0.6.5.11 | 0.7.13 | 0.8.6 | 2.0.7 | 2.1.16 | 2.2.10 | 2.3.8 | 2.4.3 | master | 12 | master | master | main | 4.0.5-FP | master | r151056 | r151058 | master | 2.3.1p1 | 2.3.1p2 | 2.4.1rc5 | main | ||
| org.zfsonlinux:allocation_classes | yes | no | no | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | no | no | no | yes | yes | yes | yes | yes | yes | yes |
| com.delphix:async_destroy | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes |
| org.openzfs:blake3 | no | no | no | no | no | no | yes | yes | yes | yes | no | no | no | no | no | no | no | no | no | yes | yes | yes | yes |
| com.fudosecurity:block_cloning | yes | no | no | no | no | no | yes | yes | yes | yes | no | no | no | no | no | no | no | no | no | yes | yes | yes | yes |
| com.truenas:block_cloning_endian | yes | no | no | no | no | no | no | no | yes | yes | no | no | no | no | no | no | no | no | no | no | no | yes | no |
| com.datto:bookmark_v2 | no | no | no | yes | yes | yes | yes | yes | yes | yes | no | yes | yes | no | no | no | yes | yes | yes | yes | yes | yes | yes |
| com.delphix:bookmark_written | no | no | no | no | yes | yes | yes | yes | yes | yes | no | no | no | no | no | no | no | no | no | yes | yes | yes | yes |
| com.delphix:bookmarks | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes |
| com.nexenta:class_of_storage | yes | no | no | no | no | no | no | no | no | no | no | no | no | no | yes | yes | no | no | no | no | no | no | no |
| org.openzfs:device_rebuild | yes | no | no | no | yes | yes | yes | yes | yes | yes | no | no | no | no | no | no | no | no | no | yes | yes | yes | yes |
| com.delphix:device_removal | no | no | no | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | no | no | yes | yes | yes | yes | yes | yes | yes | yes |
| org.openzfs:draid | no | no | no | no | no | yes | yes | yes | yes | yes | no | no | no | no | no | no | no | no | no | yes | yes | yes | yes |
| com.seagate:draid_failure_domains | no | no | no | no | no | no | no | no | no | yes | no | no | no | no | no | no | no | no | no | no | no | no | no |
| com.klarasystems:dynamic_gang_header | no | no | no | no | no | no | no | no | yes | yes | no | no | no | no | no | no | no | no | no | no | no | yes | no |
| org.illumos:edonr | no | yes1 | yes1 | yes1 | yes1 | yes1 | yes | yes | yes | yes | no | yes | yes | no | no | yes | yes | yes | yes | yes | yes | yes | yes |
| com.delphix:embedded_data | no | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | no | yes | yes | yes | yes | yes | yes | yes | yes |
| com.delphix:empty_bpobj | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes |
| com.delphix:enabled_txg | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes |
| com.datto:encryption | no | no | no | yes | yes | yes | yes | yes | yes | yes | no | yes2 | yes | no | no | no | yes | yes | yes | yes | yes | yes | yes |
| com.delphix:extensible_dataset | no | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes |
| com.klarasystems:fast_dedup | yes | no | no | no | no | no | no | yes | yes | yes | no | no | no | no | no | no | no | no | no | yes | yes | yes | yes |
| com.joyent:filesystem_limits | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes |
| com.delphix:head_errlog | no | no | no | no | no | no | yes | yes | yes | yes | no | no | no | no | no | no | no | no | no | yes | yes | yes | yes |
| com.delphix:hole_birth | no | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes |
| org.open-zfs:large_blocks | no | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | no | yes | yes | yes | yes | yes | yes | yes | yes |
| org.zfsonlinux:large_dnode | no | no | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | no | no | no | yes | yes | yes | yes | yes | yes | yes |
| com.klarasystems:large_microzap | yes | no | no | no | no | no | no | yes | yes | yes | no | no | no | no | no | no | no | no | no | yes | yes | yes | yes |
| com.delphix:livelist | yes | no | no | no | yes | yes | yes | yes | yes | yes | no | no | no | no | no | no | no | no | no | yes | yes | yes | yes |
| com.delphix:log_spacemap | yes | no | no | no | yes | yes | yes | yes | yes | yes | no | yes | yes | no | no | no | yes | yes | yes | yes | yes | yes | yes |
| org.zfsonlinux:longname | no | no | no | no | no | no | no | yes | yes | yes | no | no | no | no | no | no | no | no | no | yes | yes | yes | yes |
| org.illumos:lz4_compress | no | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes |
| com.nexenta:meta_devices | yes | no | no | no | no | no | no | no | no | no | no | no | no | no | yes | yes | no | no | no | no | no | no | no |
| com.joyent:multi_vdev_crash_dump | no | no | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes |
| com.delphix:obsolete_counts | yes | no | no | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | no | no | yes | yes | yes | yes | yes | yes | yes | yes |
| com.truenas:physical_rewrite | yes | no | no | no | no | no | no | no | yes | yes | no | no | no | no | no | no | no | no | no | no | no | yes | no |
| org.zfsonlinux:project_quota | yes | no | no | yes | yes | yes | yes | yes | yes | yes | no | yes | yes | no | no | no | yes | yes | yes | yes | yes | yes | yes |
| org.openzfs:raidz_expansion | no | no | no | no | no | no | no | yes | yes | yes | no | no | no | no | no | no | no | no | no | yes | yes | yes | yes |
| com.delphix:redacted_datasets | no | no | no | no | yes | yes | yes | yes | yes | yes | no | no | no | no | no | no | no | no | no | yes | yes | yes | yes |
| com.delphix:redaction_bookmarks | no | no | no | no | yes | yes | yes | yes | yes | yes | no | no | no | no | no | no | no | no | no | yes | yes | yes | yes |
| com.delphix:redaction_list_spill | no | no | no | no | no | no | no | yes | yes | yes | no | no | no | no | no | no | no | no | no | yes | yes | yes | yes |
| com.datto:resilver_defer | yes | no | no | yes | yes | yes | yes | yes | yes | yes | no | yes | yes | no | no | no | yes | yes | yes | yes | yes | yes | yes |
| org.illumos:sha512 | no | no | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | no | yes | yes | yes | yes | yes | yes | yes | yes |
| org.illumos:skein | no | no | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | no | yes | yes | yes | yes | yes | yes | yes | yes |
| com.delphix:spacemap_histogram | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes |
| com.delphix:spacemap_v2 | yes | no | no | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | no | no | no | yes | yes | yes | yes | yes | yes | yes |
| org.zfsonlinux:userobj_accounting | yes | no | yes | yes | yes | yes | yes | yes | yes | yes | no | yes | yes | no | no | no | yes | yes | yes | yes | yes | yes | yes |
| com.nexenta:vdev_properties | yes | no | no | no | no | no | no | no | no | no | no | no | no | no | yes | yes | no | no | no | no | no | no | no |
| com.klarasystems:vdev_zaps_v2 | no | no | no | no | no | no | yes | yes | yes | yes | no | no | no | no | no | no | no | no | no | yes | yes | yes | yes |
| com.nexenta:wbc | no | no | no | no | no | no | no | no | no | no | no | no | no | no | no | yes | no | no | no | no | no | no | no |
| org.openzfs:zilsaxattr | yes | no | no | no | no | no | yes | yes | yes | yes | no | yes | yes | no | no | no | yes | yes | yes | yes | yes | yes | yes |
| com.delphix:zpool_checkpoint | yes | no | no | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | no | no | no | yes | yes | yes | yes | yes | yes | yes |
| org.freebsd:zstd_compress | no | no | no | no | yes | yes | yes | yes | yes | yes | no | no | no | no | no | no | no | no | no | yes | yes | yes | yes |
Notes:
Table generates by parsing manpages for feature flags, and is entirely dependent on good, accurate documentation.
Last updated on 2026-07-22T12:45:47.918415Z using compatibility_matrix.py.