How to pull a single file from a Borg backup without unpacking the entire archive

Why pull a single file from a Borg archive?

When a configuration file or a database dump is corrupted, you often need only that one file, not the whole archive. Extracting the entire archive just to get a single file wastes bandwidth, CPU, and disk space—especially when the archive lives on a remote server or in a cloud bucket.

Because Borg keeps the archive compressed and deduplicated, the cost of pulling a single file is proportional to the file’s size and the number of blocks it occupies. Below is a quick walk‑through for retrieving a single file efficiently, both locally and remotely, and piping the data through other tools for immediate processing or secure transfer.


Borg basics recap

  • Repository – a directory or remote storage that holds one or more archives.
  • Archive – a snapshot of a filesystem at a point in time, identified by a name (e.g., 2026-10-07T12-00-00).
  • Encryption – Borg supports AES‑256‑CTR encryption by default; the key is stored in ~/.config/borg/keys/.
  • Remote access – Borg can talk to a remote repository over SSH using the borg command on the client and a borgserve daemon on the server.

The commands below assume you have a local repository at /srv/borg/repo and a remote one at user@backup.example.com:/srv/borg/repo.


Direct extraction with borg extract

The simplest way to pull a single file is to use borg extract with the --list flag to locate the file, then specify its path.

# List the contents of an archive
borg list /srv/borg/repo::2026-10-07T12-00-00

# Extract a single file
borg extract /srv/borg/repo::2026-10-07T12-00-00 /etc/nginx/nginx.conf

borg extract preserves the file’s metadata (permissions, ownership, timestamps) by default. If you only need the raw data, add --no-rc to skip the integrity check, but be aware that this skips the SHA‑256 verification step.

Caveats

  • Path resolution – The file path must match the archive’s internal path. If the archive was created with --exclude-caches or --exclude, the file may not exist.
  • Permissions – Running borg extract as a non‑root user will create the file with that user’s UID/GID unless --numeric-owner is used.
  • Large archives – Even though only one file is extracted, Borg still reads the archive’s index and decompresses the relevant blocks. For very large archives, this can be noticeable.

Remote extraction via SSH

When the repository is on a remote host, you can still use borg extract directly. Borg will open an SSH session and stream the data back to the client.

# Extract from a remote repository
borg extract user@backup.example.com:/srv/borg/repo::2026-10-07T12-00-00 /var/www/html/index.html

The command runs on the client; the remote side only serves the archive blocks. This keeps the bandwidth cost to the size of the requested file plus the minimal overhead of the archive index.

Security considerations

  • SSH key authentication – Use a dedicated key with authorized_keys and disable password authentication for that key.
  • Firewall – Make sure the SSH port is reachable from the client, but not open to the wider internet if possible.
  • Key rotation – Rotate the key regularly and keep the old key in a secure backup.

Piping the file for immediate use

If you just need the file content, you can pipe it straight into another command instead of writing it to disk first. Borg lets you extract a file to stdout with --output. For example, to view a config file:

borg extract --output - /srv/borg/repo::2026-10-07T12-00-00 /etc/ssh/sshd_config | less

Or to restore it into a container without touching the host filesystem:

borg extract --output - user@backup.example.com:/srv/borg/repo::2026-10-07T12-00-00 /etc/mysql/my.cnf | docker exec -i db_container mysql -u root -p < /dev/stdin

Common pitfalls

  • Wrong archive name – Double‑check the timestamp or name; Borg is case‑sensitive.
  • Missing files – If you used --exclude during backup, the file simply isn’t there.
  • Permission errors – If you’re restoring to a system that expects a specific UID/GID, use --numeric-owner or run the command as root.

TL;DR

  1. List the archive to find the exact path.
  2. Run borg extract repo::archive path/to/file.
  3. For remote repos, prepend user@host:.
  4. Use --output - to stream to another command if you don’t want a temporary file.

That’s all there is to it. Happy restoring!


See also