Skip to content

v1.3.13 — Better health-check expect-status error messaging

UX patch. The health_check_expect_status mixed-class rejection now ships actionable guidance instead of a literal restatement of the constraint.

Why

A user mid-Plex-deploy hit this:

health_check_expect_status cannot mix different status classes
(e.g. 200,301): caddy's JSON active check only supports a single
exact code or a 1xx-5xx class. Use a single code, a single class
range, or create separate target groups.

Plex returns 200 to anonymous probes on / but 401 on anything that requires auth. The natural intent "expect_status=200,401" is correctly rejected by argos because Caddy's JSON config silently degrades cross-class lists to "no status check at all". But the message tells the operator WHAT is wrong, not WHAT TO DO.

Diff

-`health_check_expect_status cannot mix different status classes
-(e.g. 200,301): caddy's JSON active check only supports a single
-exact code or a 1xx-5xx class. Use a single code, a single class
-range, or create separate target groups.`
+`health_check_expect_status: cannot combine codes from different
+status classes (e.g. 200,401). Caddy active checks accept ONE of:
+a single code (200), a comma list within ONE class (200,204), or
+a numeric range within ONE class (200-299, 400-403). Workarounds:
+pick the single most representative status; widen to a same-class
+range if you only need to confirm the backend responds; switch
+the health-check path to one that returns a consistent code (e.g.
+/identity for Plex, /System/Ping for Jellyfin); or disable active
+checks. Full guide:
+docs/operations/troubleshooting.md#health-check-expect-status-validation-rejected`

Per-backend cookbook (in the new troubleshooting entry)

Concrete health_check_path recipes for the homelab-typical backends:

Backend Path Expect Notes
Plex /identity 200 always-200 anonymous endpoint
Jellyfin /System/Ping 200 text/plain "Healthy"
*arr stack /ping 200 Sonarr / Radarr / Prowlarr / Bazarr / Readarr
Jellyseerr / Overseerr /api/v1/status 200 anonymous JSON
Nextcloud /status.php 200 JSON; works locked or unlocked
Home Assistant /manifest.json 200 static manifest, no auth
Vaultwarden /alive 200 minimal liveness endpoint

Tests

2 new tests in backend/internal/api/target_groups_validation_test.go:

  • TestExpectStatusMixedClassesMessageHasGuidance — locks in the presence of every actionable hint (single code, comma list within ONE class, numeric range within ONE class, Plex, Jellyfin, disable active checks, troubleshooting.md). A future copy-edit that strips a hint will fail this test.
  • TestExpectStatusSingleClassAccepted — happy-path regression for 200, 401, 200,204, 200-299, 400-403. The message change must not break valid inputs.

Files changed

  • backend/internal/api/target_groups.go -- the message string.
  • backend/internal/api/target_groups_validation_test.go (new).
  • docs/operations/troubleshooting.md -- new section + the earlier "unhealthy 302" entry now cross-links to it.

Upgrade

cd argos-edge
git pull
docker compose build
docker compose up -d

No data, schema, or config changes -- this is a pure string + tests + docs release.

Not changed

  • internal/caddycfg/expectstatus parser grammar is unchanged.
  • Block / detect mode AppSec wiring from v1.3.12 is unchanged.
  • The CLI argos user reset-password from v1.3.11 is unchanged.