DC-044 Add X-DashCaddy-HealthCheck marker to batch probe endpoint
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled

The dashboard polls /api/v1/services/status (not /probe/:id) for its
refresh loop. routes/services.js's requestStatusCode() didn't set the
X-DashCaddy-HealthCheck: 1 marker, so the batch endpoint hit the
forward_auth gate, got rate-limited by authLimiter (429), and reported
7 services (router, chat, sync, torrent, sonarr, radarr, prowlarr,
requests) as down.

Same fix in src/app.js /probe/:id (the single-service endpoint) for
consistency.

Without the marker, every probe from the container IP trips
authLimiter within 20 requests and the rest of the batch fails.
health-checker.js background poll was already setting the marker
correctly, which is why the cached health view showed 15/15 while
the live dashboard showed 8/15.
This commit is contained in:
Krystie
2026-07-09 02:02:45 -07:00
parent 0f04bb3638
commit 81f6049ded
2 changed files with 36 additions and 7 deletions
+15 -2
View File
@@ -86,13 +86,21 @@ module.exports = function({
reject(new Error('Timeout'));
}, PROBE_TIMEOUT);
// X-DashCaddy-HealthCheck: 1 — Caddy's (dashcaddy_auth) block matches this
// header (from local container IPs) to bypass the forward_auth gate.
// Without it, every probe hits authLimiter → 429 → marked TIMEOUT.
// See /etc/caddy/Caddyfile (dashcaddy_auth) and the matching logic in
// src/monitoring/health-checker.js (which sets the same marker).
const req = lib.request({
hostname: parsed.hostname,
port: parsed.port || (isHttps ? 443 : 80),
path: parsed.pathname + parsed.search,
method,
agent: isHttps ? probeHttpsAgent : undefined,
headers: { 'User-Agent': APP.USER_AGENTS.PROBE },
headers: {
'User-Agent': APP.USER_AGENTS.PROBE,
'X-DashCaddy-HealthCheck': '1',
},
}, (response) => {
clearTimeout(timer);
response.resume();
@@ -111,8 +119,13 @@ module.exports = function({
const pylonConfig = siteConfig?.pylon;
if (!pylonConfig?.url) return null;
try {
// Forward healthcheck marker to the remote pylon relay in case its Caddy
// is configured to bypass forward_auth on the same header.
const probeUrl = `${pylonConfig.url}/probe?url=${encodeURIComponent(targetUrl)}`;
const headers = {};
const headers = {
'User-Agent': APP.USER_AGENTS.PROBE,
'X-DashCaddy-HealthCheck': '1',
};
if (pylonConfig.key) headers['x-pylon-key'] = pylonConfig.key;
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), TIMEOUTS.HTTP_DEFAULT);