Skip to content

Backblaze B2 transient REST 500 leaves stale restic locks and breaks subsequent backups #8164

Closed

Description

@eroeinformatico

Steps to reproduce

  • Configure scheduled NS8 application backups with a Backblaze B2 destination.
  • Configure a retention policy (forget --prune --keep-last=7).
  • Run the scheduled backup.
  • The issue is intermittent and cannot currently be reproduced on demand.

During a scheduled run, the following sanitized sequence was recorded:

2026-07-16T00:05:16+02:00 Remove(<lock/c4fc23a454>) failed:
<lock/c4fc23a454> does not exist

2026-07-16T00:05:22+02:00 Load(<lock/c4fc23a454>, 0, 0)
returned error: unexpected HTTP response (500): 500 Internal Server Error

2026-07-16T00:05:25+02:00 retention policy failed:
restic forget --prune --keep-last=7 returned exit status 11

2026-07-16T00:05:30+02:00 Load(<key/afd159cbff>, 0, 0)
returned error: unexpected HTTP response (500): 500 Internal Server Error

The error affected different application repositories in the same time window, so it was not specific to Traefik application data.

Expected behavior

A transient backend error should not leave the repository permanently unusable. A later scheduled run should either safely remove a stale lock when no Restic process is active, or report a clear recovery action.

Repository access failures should not cause the agent to attempt restic init on an already initialized repository.

Actual behavior

The lock created during the failed operation remained in the B2 repository. Retention failed on every subsequent run with exit code 11:

repository is already locked by PID 1 on ns1 by root
lock was created at 2026-07-15 22:05:08

The same lock was still reported about 216 hours later and again about 240 hours later. Eventually scheduled backups failed until a manual restic unlock was performed.

A later run also tried to initialize the repository after access failed because of the lock, producing the misleading secondary error:

Fatal: create repository failed: config file already exists

Before unlocking, no Restic or backup process was running. After the manual unlock:

  • restic check succeeded on the affected repositories;
  • snapshots were readable;
  • a complete scheduled backup finished successfully.

Components

  • NS8 single-node installation
  • Backup destination: Backblaze B2
  • Image at first occurrence: ghcr.io/nethserver/restic:3.20.0
  • Current image: ghcr.io/nethserver/restic:3.21.1
  • Affected repositories included Traefik and Loki
  • The simultaneous WebTop key-load failure indicates a shared destination/gateway failure rather than an application-specific issue

No credentials, bucket names, customer identifiers or repository UUIDs are included in this report.

See also


Reported from a customer installation; all logs have been sanitized.

Activity

  1. DavidePrincipi commented on Oct 16, 2026

    @DavidePrincipi
    Member

    Analysis

    We reproduced this problem and found its causes. There are three separate parts.

    1. Restic leaves its lock after a temporary B2 error (Remove(<lock/...>) failed: ... does not exist)

    Restic does not access B2 directly: it goes through the rclone-gateway, which runs rclone serve restic. When rclone receives a DELETE request and the lookup of the file fails for any reason, it replies 404 Not Found, while a GET with the same error gets 500. Restic considers the 404 final: it does not retry, and the lock stays in the repository. The rclone-gateway sets LowLevelRetries to 1, so rclone does not retry the failed B2 request either. A single temporary B2 error is enough.

    We observed the same sequence on another installation with a B2 destination, and reproduced the rclone behavior deterministically with plain rclone and restic, without NethServer:

    2. The lock is never removed, and backups keep failing until a manual restic unlock

    Nothing removed stale locks. Fixed by NethServer/ns8-core#1351 (#8229), released in core 3.23.1: before each application backup, restic unlock removes the locks older than 30 minutes. A leftover lock now makes at most one backup run fail, and the next run removes it.

    3. Misleading restic init attempt (create repository failed: config file already exists)

    The backup ran restic init whenever restic snapshots failed, also when the repository exists but cannot be accessed, for example because of a leftover exclusive lock. NethServer/ns8-core#1366 runs restic init only when Restic reports that the repository does not exist (exit code 10), and otherwise reports the real failure.

    Issue #8239 was a duplicate of this one and has been closed.

  2. moved this from ToDo to In Progress in NethServeron Oct 19, 2026
  3. moved this from In Progress to Testing in NethServeron Oct 19, 2026
  4. DavidePrincipi commented on Oct 19, 2026

    @DavidePrincipi
    Member

    In Testing core 3.23.2-dev.1

  5. DavidePrincipi commented on Oct 19, 2026

    @DavidePrincipi
    Member

    VERIFIED

  6. removed their assignment
    on Oct 19, 2026
  7. removed
    testingPackages are available from testing repositories
    on Oct 19, 2026
  8. moved this from Testing to Verified in NethServeron Oct 19, 2026
  9. DavidePrincipi commented on Oct 19, 2026

    @DavidePrincipi
    Member
  10. moved this from Verified to Done in NethServeron Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    verifiedAll test cases were verified successfully

    Type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions