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 for200,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¶
No data, schema, or config changes -- this is a pure string + tests + docs release.
Not changed¶
internal/caddycfg/expectstatusparser grammar is unchanged.- Block / detect mode AppSec wiring from v1.3.12 is unchanged.
- The CLI
argos user reset-passwordfrom v1.3.11 is unchanged.