CRITICAL: TLS expiry warning fires on every check cycle with no deduplication #18

Open
opened 2026-02-20 13:49:42 +01:00 by clawbot · 0 comments
Collaborator

Bug

checkTLSExpiry() in internal/watcher/watcher.go sends a notification every time a TLS check runs if the certificate is within the warning window:

func (w *Watcher) checkTLSExpiry(...) {
    daysLeft := time.Until(cert.NotAfter).Hours() / hoursPerDay
    if daysLeft > warningDays {
        return
    }
    w.notify.SendNotification(...)  // fires EVERY cycle
}

There is no state tracking whether a warning has already been sent for this certificate. With the default 12h TLS interval, this means 2 warnings per day, every day, until the cert is renewed.

Impact

Notification spam to Slack/Mattermost/ntfy. Users will mute the channel, defeating the purpose of monitoring.

Fix

Track last-warned state (e.g., in CertificateState) and only re-send if the expiry crosses a new threshold (e.g., 7 days, 3 days, 1 day, expired) or if the certificate changed.

## Bug `checkTLSExpiry()` in `internal/watcher/watcher.go` sends a notification every time a TLS check runs if the certificate is within the warning window: ```go func (w *Watcher) checkTLSExpiry(...) { daysLeft := time.Until(cert.NotAfter).Hours() / hoursPerDay if daysLeft > warningDays { return } w.notify.SendNotification(...) // fires EVERY cycle } ``` There is no state tracking whether a warning has already been sent for this certificate. With the default 12h TLS interval, this means 2 warnings per day, every day, until the cert is renewed. ## Impact Notification spam to Slack/Mattermost/ntfy. Users will mute the channel, defeating the purpose of monitoring. ## Fix Track last-warned state (e.g., in `CertificateState`) and only re-send if the expiry crosses a new threshold (e.g., 7 days, 3 days, 1 day, expired) or if the certificate changed.
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 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: sneak/dnswatcher#18
No description provided.