Fix Gatus false-positive red on Authelia-protected and stale-synced sites

The auto-sync condition "[STATUS] < 400" reads as red for any site behind
Authelia's forward_auth: Gatus's probe is never logged in, so it correctly
gets a 401 back every time — the site is completely healthy, Authelia is
just doing its job, but that 401 fails the condition. Confirmed live: every
site the user actually logs into showed permanently red.

That single condition also had the opposite bug in reserve: on a genuine
outage (connection refused, DNS failure, TLS failure), Gatus reports
[STATUS] as 0, and 0 < 400 is true — a fully unreachable site would have
silently read as "up".

Fixed to two conditions together: "[CONNECTED] == true" (catches the actual
outage case) and "[STATUS] < 500" (accepts any real response, including
401/403/redirects from an auth gate, only failing on Caddy's own 502/503/504
when the backend itself is unreachable).

Also changed the sync loop to refresh conditions on already-synced
endpoints, not just add-missing-ones — the old add-if-missing-only logic
meant this fix would only apply to newly discovered domains, leaving every
already-synced site (which is most of them, on a live box) stuck on the
broken condition forever until removed and re-added by hand. Now every
sync run (every 15 minutes via the existing systemd timer, or the one that
happens immediately on a Gatus reinstall) self-heals all of them.

Verified end-to-end against the real mikefarah/yq binary: an existing
caddy-sync entry gets its conditions rewritten in place, an unrelated
manually-added endpoint is left untouched, and a newly-discovered domain
gets the corrected conditions from the start.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H4k6J1qXXyYxhGEgnJaMvn
This commit is contained in:
Claude
2026-08-11 13:39:02 +00:00
parent 304d01b0d1
commit d1d234b4d2
+22 -2
View File
@@ -262,14 +262,34 @@ EXISTING_SYNCED="$(yq e '.endpoints[] | select(.group == "caddy-sync") | .name'
ADDED=0
REMOVED=0
# [CONNECTED] == true catches an actual outage (refused/timed-out
# connection, DNS failure, TLS failure — [STATUS] reads 0 in all of those,
# which is < 400 too, so that condition ALONE would have silently reported
# a fully unreachable site as "up"). [STATUS] < 500 accepts anything the
# server actually answered with, including 401/403/redirects from an
# Authelia-protected site — Gatus's own probe is never logged in, so an
# Authelia-gated site correctly returns 401 to it every time, which is the
# site working exactly as designed, not an outage. Only Caddy's own
# 502/503/504 (backend unreachable) or a connection failure should ever
# read as down here. Confirmed live: with the old "[STATUS] < 400" alone,
# every Authelia-protected site the user actually logs into showed red
# permanently, and a would-be-real outage (STATUS=0) would have shown green.
CONDITIONS='["[CONNECTED] == true", "[STATUS] < 500"]'
while IFS= read -r domain; do
[ -z "$domain" ] && continue
# Domains only — a defensive filter, not strictly needed since these
# come from our own Caddyfile, but cheap insurance against ever
# building a yq expression out of anything unexpected.
[[ "$domain" =~ ^[a-zA-Z0-9.-]+$ ]] || continue
if ! grep -qxF "$domain" <<< "$EXISTING_SYNCED"; then
yq e -i ".endpoints += [{\"name\": \"${domain}\", \"group\": \"caddy-sync\", \"url\": \"https://${domain}\", \"interval\": \"5m\", \"conditions\": [\"[STATUS] < 400\"]}]" "$GATUS_CONFIG" \
if grep -qxF "$domain" <<< "$EXISTING_SYNCED"; then
# Already synced — refresh its conditions too, not just add-if-
# missing, so a template fix like this one reaches every
# already-added endpoint on the very next sync instead of leaving
# them stuck on whatever conditions they were first created with.
yq e -i "(.endpoints[] | select(.group == \"caddy-sync\" and .name == \"${domain}\") | .conditions) = ${CONDITIONS}" "$GATUS_CONFIG"
else
yq e -i ".endpoints += [{\"name\": \"${domain}\", \"group\": \"caddy-sync\", \"url\": \"https://${domain}\", \"interval\": \"5m\", \"conditions\": ${CONDITIONS}}]" "$GATUS_CONFIG" \
&& ADDED=$((ADDED + 1))
fi
done <<< "$CURRENT_DOMAINS"