github marcpope/borgbackupserver v2.53.0

13 hours ago

Notable change: synchronized versioning

The agent and server now share the same version number. The agent jumped from 2.29.13 to 2.53.0 to match the server. Going forward both bump together. Existing agents will auto-update on their next poll.

Bug fixes

  • Apprise email STARTTLS — the wizard was emitting mailto://…:587 URLs without an explicit mode= parameter, and apprise's default for mailto:// falls through to insecure SMTP. AWS SES (and any RFC-compliant submission server on 587) rejects AUTH-before-STARTTLS with 530 Must issue a STARTTLS command first. The wizard now always emits ?mode=ssl|starttls|insecure so the encryption mode is unambiguous regardless of scheme. Migration 084 backfills existing services using a port-based heuristic. Reported as a "forward slash in password" issue (#250 follow-up); the slash was a red herring — apprise correctly URL-decodes %2F/.
  • Apprise dispatch failures no longer flood the dashboard — push delivery problems now log at warning instead of error, so they don't conflate with backup-job failures in the Errors tile and Jobs (24h) chart. last_emailed_at is now stamped on every email attempt, not just success, so a misconfigured mailer can't loop and retry on every occurrence.
  • Recent Activity rows on client detail pages are now clickable — they navigate to the queue detail for that job, matching how /queue already worked.
  • Repository size for remote SSH repos — chained fallback now tries du -sk over SSH first (most accurate, captures FS overhead, segment files, indexes, and uncompacted data), falls back to borg info's cache.stats.unique_csize for borg-only shells like BorgBase, and finally to SUM(deduplicated_size). Combines #245 (credit @c0dr1ver) with the v2.52.2 fix from #258 (#259).

#249 — laptop offline mid-backup

A laptop that disconnected mid-backup used to leave the user in a bad spot: the in-flight backup got marked failed silently, the agent's reconnect wasn't visible in the log, no email arrived (dedup), and there was no retry. This release addresses all of it:

  • Auto-retry on offline-induced failure (default on, 3 attempts max) — when the offline sweep marks a backup failed because the agent went offline, the same plan is re-queued automatically. The agent picks it up on the next poll after reconnect. Real errors (borg path missing, repo locked, encryption failure) come in via a different path and are not retried, so a genuinely broken backup can't loop forever. Configurable in Settings → General → Agent.
  • Hysteresis on offline notifications (default 5 minutes) — the agent's status still flips to offline at the 90s threshold (so dashboards and queues react quickly), but the user-visible notification, email, and push wait until the agent has been continuously offline for at least 5 minutes. Brief network blips and short laptop suspends never become alerts. Configurable in Settings → General → Agent.
  • Reconnect log line — the offline → online transition now writes a server_log info row alongside the existing notification, so the log timeline shows the recovery, not just the outage.
  • Dedup-escalation re-email — if a backup_failed notification accumulates new occurrences and 6+ hours have passed since the last email, the email re-fires. Previously dedup silently swallowed every repeat.
  • SMTP-not-configured banner on Settings → Email — surfaces when an email_on_* toggle is enabled but SMTP isn't configured, so users aren't silently un-notified.

#247 — Dropbear SSH on agents

Enigma2, BusyBox, and embedded Linux clients use Dropbear's dbclient, which doesn't recognize OpenSSH-only options like UserKnownHostsFile and LogLevel and complains for each one. Backups completed fine but the warnings were loud. The agent now detects Dropbear at startup (parses ssh -V), strips the OpenSSH -o flags from BORG_RSH, and uses -y -y for hostkey bypass instead.

#250 — Shell hook context vars + opt-in credential exposure

The wiki documented BBS_* env vars but the agent code never set them — subprocess.run() was called without an env= parameter, so hooks only inherited the agent's plain environment.

  • BBS_ARCHIVE_NAME, BBS_REPO_PATH, BBS_BACKUP_PLAN, BBS_CLIENT_NAME, BBS_BACKUP_STATUS, BBS_DIRECTORIES, BBS_JOB_ID are now actually injected.
  • New per-config opt-in "Expose repository credentials to script (advanced)" sets BORG_PASSCOMMAND (pointing at a mode-0600 temp file) and BORG_REPO. We use BORG_PASSCOMMAND rather than BORG_PASSPHRASE because env vars are inherited by every subprocess the script spawns — BORG_PASSCOMMAND is only consulted when something explicitly shells out to read it (which is borg itself by design), so the leak surface is much smaller. The temp file is deleted as soon as the script exits. The wiki has full details and a streaming pg_dump example.

Migrations

Run automatically via bbs-update:

  • 083_offline_retry_and_notify_escalation.sql — adds retry_count, parent_job_id to backup_jobs; last_emailed_at to notifications
  • 084_apprise_mailto_mode.sql — backfills mode= on existing Apprise email services

Notes

  • Docker image will be rebuilt automatically by GitHub Actions.
  • The agent will auto-update from 2.29.x to 2.53.0 on the next poll. No manual reinstall required.

Don't miss a new borgbackupserver release

NewReleases is sending notifications on new releases.