Borgmatic sends Healthchecks.io OK ping even when there was an error #1065

Closed
opened 2025-04-09 16:47:40 +00:00 by raxod502 · 6 comments

What I'm trying to do and why

I'm using the configuration in #525 to only have a ping sent to Healthchecks.io when my backup operations have succeeded, for similar reasons as the ones described in that issue (want to only be alerted if backups are persistently down, not just having a transient error).

Steps to reproduce

source_directories:
  - "/redacted"

repositories:
  - path: "ssh://redacted"

exclude_patterns:
  - "*/.snapshots"

compression: auto,zstd
encryption_passphrase: "redacted"
ssh_command: "ssh -oIdentitiesOnly=yes -oControlPath=none -i ~/.ssh/redacted"
checkpoint_interval: 600

keep_within: 2w
keep_daily: 30
keep_weekly: 8
keep_monthly: 12

checks:
  - name: spot
    count_tolerance_percentage: 10
    data_sample_percentage: 0.01
    data_tolerance_percentage: 0.005

skip_actions:
  - compact

healthchecks:
  ping_url: "https://hc-ping.com/redacted"
  states:
    - finish

Actual behavior

Here's the output from the command:

ssh://redacted: Error running actions for repository
ssh://redacted: Command 'borg create --patterns-from /run/user/1000/borgmatic/tmp4_mkexlh --checkpoint-interval 600 --compression auto,zstd --info --progress ssh://redacted::{hostname}-{now:%Y-%m-%dT%H:%M:%S.%f}' returned non-zero exit status 2.
/home/raxod502/.config/borgmatic.d/redacted.yaml: Skipping Healthchecks log ping due to configured states
/home/raxod502/.config/borgmatic.d/redacted.yaml: Pinging Healthchecks finish
/home/raxod502/.config/borgmatic.d/redacted.yaml: An error occurred

summary:
An error occurred
Error running actions for repository
Command 'borg create --patterns-from /run/user/1000/borgmatic/tmp4_mkexlh --checkpoint-interval 600 --compression auto,zstd --info --progress ssh://redacted::{hostname}-{now:%Y-%m-%dT%H:%M:%S.%f}' returned non-zero exit status 2.

The real smoking gun for me is this though:

image.png

Why is Borgmatic sending an OK ping with a fatal error message in the body?

Expected behavior

I want an OK ping to be sent when there are no errors. Otherwise, I want nothing to be sent, or at the very least, a failure ping should be sent instead of an OK ping - the behavior of sending an OK ping unconditionally effectively means that alerting is silently disabled.

Other notes / implementation ideas

No response

borgmatic version

2.0.2

borgmatic installation method

pip install

Borg version

1.2.8

Python version

3.12.3

Database version (if applicable)

No response

Operating system and version

Ubuntu 24.04.2 LTS

### What I'm trying to do and why I'm using the configuration in https://projects.torsion.org/borgmatic-collective/borgmatic/issues/525 to only have a ping sent to Healthchecks.io when my backup operations have succeeded, for similar reasons as the ones described in that issue (want to only be alerted if backups are persistently down, not just having a transient error). ### Steps to reproduce ```yaml source_directories: - "/redacted" repositories: - path: "ssh://redacted" exclude_patterns: - "*/.snapshots" compression: auto,zstd encryption_passphrase: "redacted" ssh_command: "ssh -oIdentitiesOnly=yes -oControlPath=none -i ~/.ssh/redacted" checkpoint_interval: 600 keep_within: 2w keep_daily: 30 keep_weekly: 8 keep_monthly: 12 checks: - name: spot count_tolerance_percentage: 10 data_sample_percentage: 0.01 data_tolerance_percentage: 0.005 skip_actions: - compact healthchecks: ping_url: "https://hc-ping.com/redacted" states: - finish ``` ### Actual behavior Here's the output from the command: ``` ssh://redacted: Error running actions for repository ssh://redacted: Command 'borg create --patterns-from /run/user/1000/borgmatic/tmp4_mkexlh --checkpoint-interval 600 --compression auto,zstd --info --progress ssh://redacted::{hostname}-{now:%Y-%m-%dT%H:%M:%S.%f}' returned non-zero exit status 2. /home/raxod502/.config/borgmatic.d/redacted.yaml: Skipping Healthchecks log ping due to configured states /home/raxod502/.config/borgmatic.d/redacted.yaml: Pinging Healthchecks finish /home/raxod502/.config/borgmatic.d/redacted.yaml: An error occurred summary: An error occurred Error running actions for repository Command 'borg create --patterns-from /run/user/1000/borgmatic/tmp4_mkexlh --checkpoint-interval 600 --compression auto,zstd --info --progress ssh://redacted::{hostname}-{now:%Y-%m-%dT%H:%M:%S.%f}' returned non-zero exit status 2. ``` The real smoking gun for me is this though: <img width="632" alt="image.png" src="attachments/00f709cc-59ee-4569-8858-931c72d80435"> Why is Borgmatic sending an OK ping with a fatal error message in the body? ### Expected behavior I want an OK ping to be sent when there are no errors. Otherwise, I want nothing to be sent, or **at the very least**, a failure ping should be sent instead of an OK ping - the behavior of sending an OK ping unconditionally effectively means that alerting is silently disabled. ### Other notes / implementation ideas _No response_ ### borgmatic version 2.0.2 ### borgmatic installation method pip install ### Borg version 1.2.8 ### Python version 3.12.3 ### Database version (if applicable) _No response_ ### Operating system and version Ubuntu 24.04.2 LTS
Author

Looking at the code here and here it looks like my expected behavior is the intention of the code, but for some reason the error visible in the Borgmatic logs is not getting passed to Monitoring_hooks.__exit__ and thus Borgmatic does not realize there is an error here.

Looking at the code [here](https://projects.torsion.org/borgmatic-collective/borgmatic/src/commit/0b4aff9277eba86c53098121583c6190cad96efb/borgmatic/commands/borgmatic.py#L157-L165) and [here](https://projects.torsion.org/borgmatic-collective/borgmatic/src/commit/0b4aff9277eba86c53098121583c6190cad96efb/borgmatic/hooks/monitoring/healthchecks.py#L57-L59) it looks like my expected behavior is the intention of the code, but for some reason the error visible in the Borgmatic logs is not getting passed to `Monitoring_hooks.__exit__` and thus Borgmatic does not realize there is an error here.
Author

Okay, the bug is easy to understand: the exception is caught by this code fully inside of the context manager, thus the context manager doesn't get the exception passed to it. Should be a simple refactor to fix. Also maybe worth adding a test to ensure this doesn't regress in the future? Having the backup monitoring silently disabled is a really scary failure condition.

Okay, the bug is easy to understand: the exception is caught [by this code](https://projects.torsion.org/borgmatic-collective/borgmatic/src/commit/0b4aff9277eba86c53098121583c6190cad96efb/borgmatic/commands/borgmatic.py#L256-L280) fully inside of [the context manager](https://projects.torsion.org/borgmatic-collective/borgmatic/src/commit/0b4aff9277eba86c53098121583c6190cad96efb/borgmatic/commands/borgmatic.py#L211), thus the context manager doesn't get the exception passed to it. Should be a simple refactor to fix. Also maybe worth adding a test to ensure this doesn't regress in the future? Having the backup monitoring silently disabled is a really scary failure condition.
raxod502 changed title from Borgmatic sends Healthchecks.io ping even when there was an error to Borgmatic sends Healthchecks.io OK ping even when there was an error 2025-04-09 17:05:33 +00:00
Owner

Thanks for filing this! I think I might see the problem in code: There is logic that sends a failure ping instead of a OK ping if an error is encountered—but the error is getting swallowed by some other code before it ever makes its way to that logic. I'm not sure of the solution if that's the case, but first I'll start by seeing if I can repro the behavior you're seeing.

Thanks for filing this! I think I might see the problem in code: There _is_ logic that sends a failure ping instead of a OK ping if an error is encountered—but the error is getting swallowed by some other code before it ever makes its way to that logic. I'm not sure of the solution if that's the case, but first I'll start by seeing if I can repro the behavior you're seeing.
Owner

Oh, hah, just saw your comments. Look like you figured it out first! And yes, I agree that: 1. A refactor might fix this, and 2. Absolutely a regression test would be a good idea.

Oh, hah, just saw your comments. Look like you figured it out first! And yes, I agree that: 1. A refactor might fix this, and 2. Absolutely a regression test would be a good idea.
Owner

This is fixed in main and will be part of the next release. The solution I went with was re-raising the exception after all repositories had a chance to run, so that one repository erroring doesn't interfere with other repositories running. And there's a regression test as well.

Thanks again!

This is fixed in main and will be part of the next release. The solution I went with was re-raising the exception after all repositories had a chance to run, so that one repository erroring doesn't interfere with other repositories running. And there's a regression test as well. Thanks again!
Owner

Released in borgmatic 2.0.3!

Released in borgmatic 2.0.3!
Sign in to join this conversation.
No milestone
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
borgmatic-collective/borgmatic#1065
No description provided.