Restic Repository Locked After a Crash: Causes, Checks, and Fixes

Eva Wong is the Technical Writer and resident tinkerer at ZimaSpace. A lifelong geek with a passion for homelabs and open-source software, she specializes in translating complex technical concepts into accessible, hands-on guides. Eva believes that self-hosting should be fun, not intimidating. Through her tutorials, she empowers the community to demystify hardware setups, from building their first NAS to mastering Docker containers.

A Restic repository can remain locked because another process is still alive, a crash left stale state, the backend delayed updates, or maintenance still holds an exclusive lock.

On a multi-host home server, the dangerous assumption is that the last visible crash created the only lock. A prune job may still be running elsewhere, a container may have restarted with the same schedule, or object storage may not show the newest state immediately. Start by freezing new schedules and reading the lock identity; remove a lock only after its host, process, time, and repository activity all point to a dead operation.

Read the Lock Identity Before Taking Action

Pause new backup, forget, check, and prune schedules on every machine that can reach the repository. List the locks and save their host, process ID, user, creation time, refresh time, and exclusive or non-exclusive role. Then inspect the matching process and service logs on the named host rather than guessing from age alone.

Stale locks commonly follow an interrupted Restic process, but an interrupted pipeline is only one possible cause. A process receiving an unclean signal may leave state that looks similar to a remote job still working.

If the PID is alive and logs are advancing, wait or stop the job through its service manager; do not unlock underneath it. If the process is absent and the host has not restarted the same job, the lock becomes a stale candidate. If the host is unreachable or the backend view is inconsistent, the status remains unverified and no destructive action is justified.

Separate the Four Lock Signatures

A live writer has a matching process, current log activity, and a lock that refreshes. An unclean exit has no live process and a fixed lock timestamp after the host or container stopped. Backend delay appears when clients disagree about the lock list or timestamps lag known repository activity. Unfinished maintenance shows an exclusive lock and a check or prune log that still changes.

A broad Restic troubleshooting order keeps repository locks, prune failures, and possible corruption as separate branches so a stale-lock fix is not applied to a storage fault.

Test one signature at a time. Confirm liveness first, then compare timestamps and logs, then check backend reachability and clock, and finally inspect maintenance. If two signatures remain plausible, keep the lock and investigate the safer branch; unlocking is not the diagnostic test because it changes the protection you are trying to understand.

Clear Only a Proven Stale Lock

Before unlocking, check every client, automation controller, container host, and repository-side service one more time. Save the current lock list and recent logs. Use the normal stale-lock removal command, not a remove-all or no-lock option, because the standard path is designed to leave active locks in place.

A real-world stale lock failure can stop an otherwise established backup schedule, but the age of one case does not define a universal safe deletion threshold.

If the standard command removes the stale record and no lock immediately returns, proceed to a read-only repository listing. If it refuses because the lock is active, stop and find the owner. If a new lock appears at once, a scheduler or restarted container is still running; disable that source before attempting another repair.

-15% OFF
Single board computer zimaboard2

Re-Test the Original Operation and Watch for Recurrence

Run the same operation that failed, with progress and exit status captured. Watch the lock appear, refresh while the job is active, and disappear after a clean exit. Then allow one normal scheduled cycle to run. This reproduces the original trigger and proves more than a successful repository listing.

If the repository becomes read-only or maintenance fails after the lock clears, follow the separate interrupted-prune recovery path rather than repeatedly unlocking.

Recovery passes when two original-load cycles complete, each lock is refreshed while active and removed on exit, and a repository check or sample restore behaves normally. Escalate if locks recur after clean exits, clients disagree about backend state, or check reports missing or damaged repository objects. Keep locking enabled throughout that investigation.

Support & Tips

More to Read

Get More Builds Like This

Stay in the Loop

Get updates from Zima - new products, exclusive deals, and real builds from the community.

Stay in the Loop preferences

We respect your inbox. Unsubscribe anytime.