restic
Identity
| Property | Value |
|---|---|
| Binary | restic |
| Unit | No daemon — run via cron or systemd timer |
| Config | No fixed path — driven by env vars or CLI flags |
| Backends | local, SFTP, S3/MinIO/Wasabi, Backblaze B2, REST server, Azure Blob, GCS |
| Type | CLI backup tool (content-addressed deduplication + AES-256 encryption) |
| Install | apt install restic / dnf install restic / brew install restic / binary from GitHub releases |
| Self-update | restic self-update (updates the binary in-place) |
Key Operations
| Task | Command |
|---|---|
| Initialize repo (local) | restic -r /path/to/repo init |
| Backup path | restic -r /path/to/repo backup /home /etc |
| Backup with excludes | restic -r /repo backup /home --exclude-caches --exclude '*.pyc' |
| List snapshots | restic -r /repo snapshots |
| Filter snapshots by host | restic -r /repo snapshots --host myhostname |
| Restore latest | restic -r /repo restore latest --target /tmp/restore |
| Restore single path from snapshot | restic -r /repo restore abc1234 --include /home/user/file.txt --target /tmp/ |
| Forget (apply retention policy) | restic -r /repo forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 |
| Forget AND prune in one command | restic -r /repo forget --prune --keep-daily 7 --keep-weekly 4 --keep-monthly 6 |
| Prune (free disk space) | restic -r /repo prune |
| Check metadata integrity | restic -r /repo check |
| Check + verify all data chunks | restic -r /repo check --read-data |
| FUSE mount repo | restic -r /repo mount /mnt/restic |
| Stats | restic -r /repo stats |
| Diff two snapshots | restic -r /repo diff abc1234 def5678 |
| Unlock stuck repo | restic -r /repo unlock |
| Repair after interrupted prune | restic -r /repo repair packs && restic -r /repo prune |
| List repo keys | restic -r /repo key list |
| Add new key | restic -r /repo key add |
| Update binary | restic self-update |
Expected State
restic -r /repo checkexits 0 with no errors printedrestic -r /repo snapshotslists recent snapshots covering expected paths and hosts- Retention policy applied on a schedule (cron or systemd timer) with
forget --pruneorforgetfollowed byprune - Repository password and path stored securely and separately from the machine being backed up
Health Checks
restic -r /repo snapshots 2>&1 | tail -5— lists recent snapshots; confirms repo is accessible and password is correctrestic -r /repo check 2>&1— verifies repository structure and metadata; exits 0 on successrestic -r /repo stats 2>&1 | grep -E 'Total|Snapshots'— shows dedup stats and snapshot count without a full data read
Common Failures
| Symptom | Likely cause | Check/Fix |
|---|---|---|
Fatal: wrong password or no key found |
Incorrect password or wrong repo path | Verify RESTIC_REPOSITORY and RESTIC_PASSWORD / RESTIC_PASSWORD_FILE env vars |
Fatal: unable to open config file: ...is already locked |
Previous backup crashed while holding repo lock | Verify no backup is running: pgrep restic; then restic -r /repo unlock |
FUSE mount fails: fusermount: exec: "fusermount": executable file not found |
fuse package not installed |
apt install fuse / dnf install fuse; user needs to be in the fuse group or run as root |
S3: error: 403 Forbidden |
Wrong credentials or missing bucket permissions | Check AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION; verify bucket policy grants s3:GetObject, s3:PutObject, s3:DeleteObject, s3:ListBucket |
repository has unfinished operations |
prune was interrupted, leaving partial pack files |
restic -r /repo repair packs then re-run prune |
Backup runs but df shows no disk change after forget |
forget only removes snapshot metadata, not data |
Run restic prune after forget, or use forget --prune |
Fatal: snapshot ID does not exist |
Short snapshot ID collision or stale ID in a script | Use full 64-char IDs or latest keyword; get current IDs with restic snapshots |
Pain Points
-
forgetandpruneare separate commands —restic forget --keep-daily 7marks old snapshots for deletion and removes them from the snapshot list, but does NOT free disk space. The underlying data blobs are still on disk until you runrestic prune. To do both in one step, userestic forget --prune --keep-*. Many users runforgetexpecting disk usage to drop immediately, then wonder why nothing changed. -
No recovery without the password — Restic repositories are encrypted with AES-256 using a key derived from the password. There is no recovery path if the password is lost. Store it in a password manager (vaultwarden, keepass) alongside the repository URL, and test that you can list snapshots from a clean machine before an emergency occurs.
-
checkvscheck --read-data—restic checkverifies the repository structure and snapshot metadata quickly (seconds to minutes).restic check --read-datadownloads and verifies every data chunk against its stored hash — this is slow (hours for large repos) but the only way to verify the actual backup data hasn't been corrupted or partially deleted. Run--read-dataon a weekly or monthly schedule, not after every backup. -
Exclude caches and temp dirs explicitly — Without exclusions, restic backs up
~/.cache,/tmp, browser cache directories,node_modules,.venv,.tox, and similar volatile trees. Use--exclude-caches(respectsCACHEDIR.TAGfiles that tools like pip and npm write automatically) plus explicit--excludepatterns for the rest. A backup that includes gigabytes of caches wastes space and slows both backup and prune. -
Lock file deadlock with parallel runs — Two simultaneous
restic backupcommands against the same repository will deadlock on the lock file — the second run will fail immediately with a "repository is already locked" error. For cron/systemd automation, useConflicts=in the systemd service or a script-level lock guard (flock) to prevent overlapping runs. -
Snapshot IDs are not stable across forget/prune cycles — Short IDs (8 hex chars) are computed from the full 64-char SHA-256 prefix and can collide as the repository grows. Scripts should use either the full 64-char ID or the
latestkeyword. Always retrieve current IDs withrestic snapshotsrather than storing them long-term.
References
See references/ for:
cheatsheet.md— 10 task-organized patterns with copy-paste commandscommon-patterns.md— backend setup, systemd timer automation, rest-server, retention policiesdocs.md— official documentation links