About this article: AI-assisted writing, reviewed against the cited sources. This is source research, not a lab validation of the procedures. Check the stated versions and your own recovery requirements before making changes.
Btrfs snapshots are fast, cheap and easy to schedule. Several Linux distributions take them automatically before software updates, and administrators often keep hourly or daily snapshots of important data. Rolling back a bad update or recovering a deleted file from last night's snapshot is quick and genuinely useful.
The risk is that the convenience gets mistaken for protection. The Btrfs project's own documentation is direct about it. This guide covers what snapshots do and do not protect, how btrfs send and btrfs receive turn snapshots into copies on separate storage, the things that break an incremental chain, and the cautious order of steps when a Btrfs filesystem refuses to mount.
Why it matters
The Btrfs subvolume documentation carries a note that every team using Btrfs should read:
"A snapshot is not a backup: snapshots work by use of BTRFS' copy-on-write behaviour. A snapshot and the original it was taken from initially share all of the same data blocks. If that data is damaged in some way (cosmic rays, bad disk sector, accident with dd to the disk), then the snapshot and the original will both be damaged."
It continues: snapshots "are useful to have local online 'copies' of the filesystem that can be referred back to, or to implement a form of deduplication, or to fix the state of a filesystem for making a full backup without anything changing underneath it. They do not in themselves make your data any safer."
That last use is the important one for recovery. A read-only snapshot fixes the filesystem view for copying. It does not by itself make a running application consistent across memory, logs or multiple subvolumes. It is not the backup itself. If the disks fail, the filesystem is damaged, the server is lost or someone with administrative access deletes the filesystem, the snapshots go with it.
How it works
Snapshots and subvolumes
In Btrfs, a subvolume is "a part of filesystem with its own independent file/directory hierarchy and inode number namespace", and "a snapshot is also subvolume, but with a given initial content of the original subvolume". The documentation contrasts this with LVM: Btrfs subvolumes are "file extent-based", not block-level.
One detail catches many people out. The documentation states that "snapshotting is not recursive, so a subvolume or a snapshot is effectively a barrier and no files in the nested subvolumes appear in the snapshot." In their place is an empty stub. If a system has, for example, a separate subvolume for a database directory or for home directories inside the root subvolume, a snapshot of root does not contain them. Each subvolume you care about needs its own snapshot and its own backup. (our reading of the consequence)
Snapshots are read-write by default. For backup use they should be read-only, which the next section explains.
Send and receive
The send/receive overview describes them as "complementary features that allow to transfer data from one filesystem to another in a streamable format". Send "traverses a given read-only subvolume and either creates a full stream representation of its data and metadata (full mode), or given a set of subvolumes for reference it generates a difference relative to that set (incremental mode)". Receive "takes the stream and reconstructs a subvolume with files and directories equivalent to the filesystem that was used to produce the stream."
The stream can be "sent over network, piped directly to the receive command or saved to a file", and each command in it is protected by a CRC32C checksum.
The overview also sets expectations: "The result is not exactly 1:1, e.g. inode numbers can be different and other unique identifiers can be different (like the subvolume UUIDs)." For most file restores this does not matter. It matters if anything depends on inode numbers or subvolume identifiers.
The btrfs-send manual explains why snapshots must be read-only: "All snapshots involved in one send command must be read-only". A read-only mount is not enough, because "there's no way to guarantee that there won't be any other writable mount of the same subvolume".
What an incremental chain depends on
Incremental sends (-p parent and -c clone sources) are what make regular copies practical: only changes since the parent are sent. They depend on the parent being identical on both sides. The send manual is emphatic: "You must not specify clone sources unless you guarantee that these snapshots are exactly in the same state on both sides--both for the sender and the receiver."
The btrfs-subvolume manual explains how received snapshots are tracked. A received snapshot is read-only and carries a received_uuid "which identifies the subvolume on the filesystem that produced the stream". Changing a received snapshot to read-write "requires to reset the received_uuid", and doing so with btrfs property set "requires force", because it "could potentially break the incremental send use case." The manual notes that these safety checks arrived in 5.14.2, and that older received subvolumes with read-write status "may exist and could still lead to problems".
Practical points for keeping a chain healthy (our recommendations, drawn from the sources above):
- Keep the most recent common parent on both sides. Deleting it can break the intended next incremental send. An older unchanged common parent or suitable shared clone sources may still be usable; otherwise a new full send is needed.
- Never make backup copies read-write in place. To work with restored data, take a new writable snapshot of the received one and use that.
- Keep the receiving location quiet during a receive. The btrfs-receive manual warns that while a receive is in progress, users with write access "can add, remove, or modify files, in which case the resulting read-only subvolume will not be an exact copy". It also lists failures: receive fails if the subvolume already exists, if a "previously received subvolume has been changed after it was received", or if the default subvolume has changed.
Treat streams as trusted input only
The receive manual includes a security warning worth repeating: receive "does not currently do a very good job of validating that an incremental send stream actually makes sense", and "a specially crafted send stream" could create reflinks to arbitrary files on the same filesystem. "Users are advised to not use btrfs receive on send streams from untrusted sources, and to protect trusted streams when sending them across untrusted networks."
In practice, this means encrypting and authenticating streams in transit, protecting stored stream files from tampering, and receiving into a filesystem dedicated to backups rather than one holding other sensitive data.
Saved stream files
Send can write to a file with -f, and receive can check a stream without changing anything: --dump "will only do the validation of the stream, and print the stream metadata", and "the filesystem remains unchanged."
A stream file saved as a backup is only restorable by btrfs receive onto a Btrfs filesystem, and an incremental stream is only usable on top of its exact parent. Keep the full starting stream and every parent or clone dependency required by the chosen target. A linear chain requires all its intervening changes; branched histories need an explicit dependency record. Receiving copies onto a separate Btrfs filesystem tends to be easier to verify than keeping stream files, because the result can be browsed and checked.
Two version notes from the send manual matter for long-lived copies: send protocol version 2 "requires at least btrfs-progs 6.0 on both the sender and receiver and at least Linux 6.0 on the sender", and it is required for --compressed-data. If your recovery host may be older, check what protocol your sends use.
What to choose and why
- Use snapshots for fast, local rollback, and send read-only snapshots to separate storage, preferably another machine, for protection. The second copy is the backup.
- Snapshot every subvolume that matters, remembering that snapshots do not include nested subvolumes.
- Test restores by receiving into a scratch location and comparing file lists and checksums against the source snapshot. A successful receive is a good sign but not proof that the right data is there.
- Watch the health of the source. The btrfs-scrub manual describes scrub as "a validation pass over all filesystem data and metadata that detects data checksum errors". On replicated profiles such as RAID1, "read-write scrub will also automatically repair any damage by copying verified good data from one of the other replicas". It also warns that files marked NOCOW (
chattr +C) lose data checksums, so scrub validates their metadata but not their data. Databases and virtual machine images are often set NOCOW, so for those files, application-level checks and backups matter more.
When a Btrfs filesystem will not mount
This is where caution matters most. The documented tools differ greatly in risk. Nothing here should be run against your only copy of important data without first taking an image of the devices or confirming that a current backup exists.
1. Record the error
The kernel log at the failed mount usually names the problem: log replay, a damaged tree root, a missing device or a size mismatch. Several tools in the btrfs-rescue manual each target one specific error and include sample messages to match against.
2. Assess mount behaviour before access
The Btrfs mount options include rescue= modes, available since kernel 5.9, which all require a read-only mount; the documentation says the mode "doesn't allow remount to read-write". They include usebackuproot (try the backup tree roots kept in the superblock), nologreplay (do not replay the log), and, from 5.11, ignorebadroots, which can "greatly improve the chance for data salvage", and ignoredatacsums. The documentation notes that the behaviour of usebackuproot changed in kernel 7.4, which added options to choose an exact backup slot.
Ordinary read-only mounting is not enough to suppress tree-log replay: the mount-options manual explicitly warns that replay can still occur and documents no-log-replay control. Choose an access method only after preserving unstable media and understanding those writes. If access succeeds, copy important data to independent storage. Data obtained while checksum checks are ignored must be treated as unverified salvage, not an intact backup.
For multi-device filesystems with a missing disk, the degraded option allows a mount "with fewer devices than the RAID profile constraints require". Read-write degraded mounts can fail when too many devices are missing, and any replacement should follow the btrfs-replace manual. The Btrfs status page adds that replace and device delete "insist on being able to read or reconstruct all data" and abort on read errors.
3. Understand checking separately from repair
The btrfs-check manual states that "by default, btrfs check will not modify the device". It is recommended on an unmounted filesystem. Its --mode lowmem option addresses the high memory needed on large filesystems.
The same manual carries a clear warning about its repair mode:
"Do not use --repair unless you are advised to do so by a developer or an experienced user, and then only after having accepted that no fsck successfully repair all types of filesystem corruption."
4. Consider salvage without mounting
If the filesystem cannot be mounted at all, btrfs-restore is designed "to try to salvage files from a damaged filesystem and restore them into path". The manual says "the filesystem image is not modified", that checks are "less strict", and warns that "some data might be incomplete or from older versions". It offers a dry run (-D) that lists what would be recovered, and options to restore extended attributes (-x), ownership, modes and times (-m) and symbolic links (-S). Without those options, restored files may lack the metadata the original system expects. Restored files must go to a different, healthy filesystem with enough space.
5. Leave metadata repair to a qualified recovery plan
The btrfs rescue subcommands each fix one specific problem. Some carry stated costs: zero-log "may fix a specific set of problem when the filesystem mount fails during log replay", but "clearing the log may lead to loss of changes that were made since the last transaction commit", which "may be up to 30 seconds". chunk-recover scans whole devices and "will be very slow". The manual also notes that none of the rescue subcommands can handle an ongoing replace or balance. Matching an error message is not sufficient authority to modify damaged metadata. Preserve copies and obtain a qualified recovery assessment before selecting any repair operation.
Risks and limits
- Versions matter. Several options are tied to kernel or btrfs-progs versions, and the documentation consulted is the "latest" set, independently read on 13 November 2026. Older rescue media may lack them.
- RAID5 and RAID6 profiles have separate documented status and recommended practices, linked from the status page and not covered here.
- Nothing here was run. All commands and options are quoted from the documentation for planning.
- Application consistency. A snapshot of a running database is crash-consistent at best. Databases need their own backup method or a quiesce step. Include every data and log location required by the application's supported recovery method.
Sources
- Btrfs Subvolumes: https://btrfs.readthedocs.io/en/latest/Subvolumes.html
- Btrfs Send/receive: https://btrfs.readthedocs.io/en/latest/Send-receive.html
- btrfs-send(8): https://btrfs.readthedocs.io/en/latest/btrfs-send.html
- btrfs-receive(8): https://btrfs.readthedocs.io/en/latest/btrfs-receive.html
- btrfs-subvolume(8): https://btrfs.readthedocs.io/en/latest/btrfs-subvolume.html
- btrfs-scrub(8): https://btrfs.readthedocs.io/en/latest/btrfs-scrub.html
- Btrfs mount options: https://btrfs.readthedocs.io/en/latest/ch-mount-options.html
- btrfs-check(8): https://btrfs.readthedocs.io/en/latest/btrfs-check.html
- btrfs-restore(8): https://btrfs.readthedocs.io/en/latest/btrfs-restore.html
- btrfs-rescue(8): https://btrfs.readthedocs.io/en/latest/btrfs-rescue.html
- btrfs-replace(8): https://btrfs.readthedocs.io/en/latest/btrfs-replace.html
- Btrfs Status: https://btrfs.readthedocs.io/en/latest/Status.html
This article was originally published on .