Home / Alt manpages / btrfs-receive(8)

  • btrfs-receive(8)
  • Admin command
  • linux

Safely Receive a Btrfs Snapshot from a Send Stream

You will receive a Btrfs send stream into an existing filesystem and keep the destination protected while it runs. Then you verify the result properly rather than trusting a clean exit code. The examples use btrfs-progs 6.6.3, installed here as package version 6.6.3-1.1build2.

Allow 15 to 30 minutes, excluding the time needed to copy the stream. You need a readable stream produced by btrfs send, a mounted destination Btrfs filesystem, and enough free space. Receiving changes the destination filesystem, so take a checkpoint before starting. The normal receive command needs elevated privileges on many systems.

1. Check the installed command

Confirm the binary and its version before relying on option details:

$ command -v btrfs
/usr/bin/btrfs
$ btrfs --version
btrfs-progs v6.6.3
$ btrfs receive --help
usage: btrfs receive [options] <mount>

The subcommand takes a destination path for normal receiving. It reads the stream from standard input unless you give -f FILE. Do not confuse the destination path with an ordinary directory on another filesystem: it must be in the Btrfs filesystem that will contain the received subvolume.

Checkpoint

Write down the exact stream file and destination path you intend to use. If either is a placeholder, stop here and replace it before continuing.

2. Inspect the stream without changing the filesystem

Use --dump when you need to validate a stream and see its metadata without providing a destination:

$ btrfs receive --dump -f /path/to/snapshot.stream
subvol             path=project-2026-09-22
uuid               uuid=REPORTED-UUID
transid            transid=REPORTED-TRANSACTION
...                ...

The exact operations, UUID and transaction values depend on the stream. The useful result is one metadata operation per line. In this mode the filesystem remains unchanged, and the path argument is not required. A non-zero exit status means the validation failed. Keep the stream if you need to investigate the error; do not edit it in place.

There is a distraction trap here: --dump is a receiver-side stream inspection mode, not a dry run for a normal destination. It validates and prints metadata, but it does not prove that a particular destination has the required mount layout or free space.

3. Confirm the destination mount

Inspect the destination before granting the receive process access to it:

$ findmnt --target /srv/btrfs-receive
TARGET              SOURCE     FSTYPE OPTIONS
/srv/btrfs-receive  /dev/...   btrfs  ...
$ btrfs filesystem usage /srv/btrfs-receive
Overall:
    Device size: ...
    Device allocated: ...
    Device unallocated: ...

Use a real path in place of /srv/btrfs-receive. The mount must expose the top level of the destination filesystem, not merely a nested subvolume. The receive documentation treats a changed default subvolume or a mount that is not at the filesystem top level as a failure condition.

If /proc is not available, such as inside a chroot, pass the root mount point with -m /path/to/root-mount. This option tells receive where the destination filesystem is mounted; it does not mount the filesystem for you. Mounting or changing storage layout is an administrative action outside this workflow.

4. Protect the receiving path

Before receiving, stop jobs and users that can write below the destination path. A successful receive makes the new subvolume read-only only after the operation finishes. During the copy, a user with write access can add, remove or modify files, leaving a result that is not an exact copy of the sent snapshot.

This is a security and integrity boundary, not a cosmetic precaution. Use the maintenance controls appropriate to your host, such as stopping a writer service or restricting access at the mount and directory level. Record what you changed so it can be restored after verification. Do not make a live production path writable to everyone as a quick workaround.

Checkpoint

Verify that the stream has passed inspection, the destination is the intended Btrfs top level, and writers are excluded. If you cannot answer all three, do not start receive.

5. Receive the stream

For a stream file, run the ordinary receive as the account that has the required Btrfs access:

$ sudo btrfs receive -f /path/to/snapshot.stream /srv/btrfs-receive
At subvol project-2026-09-22
Receiving snapshot project-2026-09-22

Alternatively, use a pipe when the sender and receiver are connected directly:

$ sudo btrfs send /path/to/read-only-snapshot | sudo btrfs receive /srv/btrfs-receive

Only use the pipeline when the source snapshot is read-only and the sender and receiver have been checked independently. Keep the sender's output and receiver's errors visible while testing. A zero exit status means receive succeeded; any other status means it failed.

-e makes the receiver terminate after an end marker in the stream. Without it, the receiver waits for end-of-file or an error. Use it only when the stream format and transport are under your control. -E N changes the error limit from its default of one; -E 0 means no limit. Raising that limit can allow more stream errors before termination, so it is not a general repair option.

6. Verify the received subvolume

Check the command status immediately, then inspect the destination subvolume:

$ printf 'receive exit status: %s\n' "$?"
receive exit status: 0
$ sudo btrfs subvolume list /srv/btrfs-receive
ID ... gen ... top level ... path project-2026-09-22
$ sudo btrfs property get -ts /srv/btrfs-receive/project-2026-09-22 ro
ro=true

The subvolume name is taken from the stream, so replace project-2026-09-22 with the path shown by the list command. The read-only property is the important completion check. Preserve the original stream and source snapshot until you have checked the files and any application-specific backup test.

There is no normal undo operation that returns the received data to a previous state. If the receive created an unwanted subvolume, identify it exactly with btrfs subvolume list and remove it only after confirming that it contains no needed data. Subvolume deletion is destructive and should be a separately reviewed maintenance action, not an automatic error handler.

7. Diagnose the common failures

  • Already exists: the receiving subvolume name is present. Choose a clean destination or remove the existing subvolume only after a deliberate data review.
  • Changed received parent: a previously received subvolume was modified after receipt. Restore its expected read-only, unchanged state or create a new receive target; do not force an incremental stream past this check.
  • Wrong mount level: remount or select the filesystem top level. If /proc is unavailable, check whether -m supplies the real root mount.
  • Unexpected stream failure: rerun --dump against the saved stream and check the sender and receiver versions, paths and available space.
  • Untrusted stream: stop. Btrfs receive is not a safe parser for arbitrary input. A specially crafted stream can create reflinks to arbitrary files in the same filesystem. Receive only trusted streams, and protect trusted streams when transporting them across an untrusted network.

Do not treat a verbose log as proof of data integrity. --verbose shows more performed operations, while --quiet suppresses normal messages and leaves errors. Use the mode that helps you observe the operation, then verify the subvolume and its contents separately.

Done means

  • Version and stream checked. The installed btrfs-progs version and stream format were confirmed.
  • Stream inspected safely. --dump validated the saved stream without changing the destination filesystem.
  • Destination confirmed. It is the intended Btrfs top-level mount with enough space.
  • Writers excluded. Nothing could write below the destination until receive completed and the subvolume became read-only.
  • Exit status checked. Receive returned zero, and btrfs subvolume list found the expected path.
  • Read-only confirmed. The received subvolume reports ro=true, and the original stream remains available for recovery or audit.